mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-03 14:26:15 +00:00
Compare commits
167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7600372ca1 | ||
|
|
54cd5b5e0e | ||
|
|
ede6fcd7dd | ||
|
|
eaeacbd8de | ||
|
|
0ffed00bcb | ||
|
|
c0c3d6b30e | ||
|
|
9c59a83f04 | ||
|
|
95436cb073 | ||
|
|
cbb5502a40 | ||
|
|
d6dfe85f69 | ||
|
|
ae9af1470c | ||
|
|
9255c70b0b | ||
|
|
53c514ecc6 | ||
|
|
e348d59a7e | ||
|
|
244d27341f | ||
|
|
3a55b62907 | ||
|
|
0c3ae43910 | ||
|
|
8436586566 | ||
|
|
19d1245379 | ||
|
|
470eeac821 | ||
|
|
9c6aa86e68 | ||
|
|
1362471657 | ||
|
|
aa46b454e2 | ||
|
|
02465c529d | ||
|
|
c68cbf8946 | ||
|
|
46542c1dce | ||
|
|
97f58dd413 | ||
|
|
4bedfc8e96 | ||
|
|
cd17df5cc2 | ||
|
|
0b589a74c9 | ||
|
|
1260515a40 | ||
|
|
007cd6573e | ||
|
|
7b022f9907 | ||
|
|
96c9c89238 | ||
|
|
b4949af1d7 | ||
|
|
85086909a6 | ||
|
|
79209219dd | ||
|
|
18e1b7a2bb | ||
|
|
a5766639d6 | ||
|
|
191fbf083d | ||
|
|
8c4342853a | ||
|
|
3937ac1ae7 | ||
|
|
a128099619 | ||
|
|
deed24f6e8 | ||
|
|
ac2db7c73f | ||
|
|
06db6d0341 | ||
|
|
2d43e11e96 | ||
|
|
8911158f81 | ||
|
|
a714dc3188 | ||
|
|
29445f65ce | ||
|
|
48be292850 | ||
|
|
2397f45d3f | ||
|
|
d1fb67f1f0 | ||
|
|
eae6d11476 | ||
|
|
452fc1e484 | ||
|
|
de3888618a | ||
|
|
4678701f42 | ||
|
|
7481ba4539 | ||
|
|
d791e2ac92 | ||
|
|
a60ff48c08 | ||
|
|
da3b49aa12 | ||
|
|
e505874af9 | ||
|
|
2f0a9fba99 | ||
|
|
b034072027 | ||
|
|
f94b9adf7a | ||
|
|
c95178ea59 | ||
|
|
1f7c498bd9 | ||
|
|
e46d4b2f0e | ||
|
|
f2b34543f9 | ||
|
|
d32da036bc | ||
|
|
8b0f4f99f6 | ||
|
|
17e887442c | ||
|
|
fc454cd11e | ||
|
|
e0e2607632 | ||
|
|
25f28e7fee | ||
|
|
ba9719ed67 | ||
|
|
bb04d1bfe1 | ||
|
|
82e58e6513 | ||
|
|
274a1dac7c | ||
|
|
ae7f8f44e3 | ||
|
|
a82b9fb36f | ||
|
|
3488136ca4 | ||
|
|
05ffa0b638 | ||
|
|
942cc78406 | ||
|
|
46690b5bbf | ||
|
|
cc4e322065 | ||
|
|
915c05c57c | ||
|
|
adba66afb9 | ||
|
|
cc42a5e0ab | ||
|
|
c8a1b77a54 | ||
|
|
b9d252fd8a | ||
|
|
2b02475fd4 | ||
|
|
8aa7a67100 | ||
|
|
348090a127 | ||
|
|
c0df995e28 | ||
|
|
8c9d3a5455 | ||
|
|
9dcfa1dca4 | ||
|
|
bd4cfe06b1 | ||
|
|
9c7034e401 | ||
|
|
aeb167c1e8 | ||
|
|
7967ec38e8 | ||
|
|
250be2ccdc | ||
|
|
6158069d4d | ||
|
|
b2e5b8d2d3 | ||
|
|
5db1b48e07 | ||
|
|
56dcfcc5ed | ||
|
|
7c1106a46a | ||
|
|
9afdfd4d1b | ||
|
|
c2f260a86c | ||
|
|
2781179b4b | ||
|
|
3b479abf64 | ||
|
|
c731718f50 | ||
|
|
0fd0a9fe7e | ||
|
|
302582bfe1 | ||
|
|
35ad09dd5f | ||
|
|
8ed2921ec1 | ||
|
|
1bf7faa34d | ||
|
|
8ead91c527 | ||
|
|
5e602a651c | ||
|
|
0993b2a463 | ||
|
|
73ada2b541 | ||
|
|
f9bd0967bc | ||
|
|
16b13c074e | ||
|
|
0a9a883ca4 | ||
|
|
a91735531a | ||
|
|
f98ff3f502 | ||
|
|
5dfb5f3b88 | ||
|
|
54e1beb548 | ||
|
|
839bb48cd6 | ||
|
|
c4ebdda1a4 | ||
|
|
d6b494c6c4 | ||
|
|
a80d4f5147 | ||
|
|
811b04485c | ||
|
|
a64fead653 | ||
|
|
399461d1b1 | ||
|
|
ec5e8ed5b3 | ||
|
|
5655164e60 | ||
|
|
3d9b7c2d67 | ||
|
|
764e3ab5c1 | ||
|
|
3314362faf | ||
|
|
e483f520db | ||
|
|
c92e32c0e1 | ||
|
|
cb872f8a41 | ||
|
|
0aae245054 | ||
|
|
480a7d038f | ||
|
|
f62f44d4c0 | ||
|
|
e316b89fb1 | ||
|
|
3b2dbcac1b | ||
|
|
d881c9faf6 | ||
|
|
11d9375f36 | ||
|
|
4207d7adcf | ||
|
|
832b1d66a0 | ||
|
|
cd829f9f22 | ||
|
|
f7c70eb6df | ||
|
|
01960f6470 | ||
|
|
f6065a1c00 | ||
|
|
ba3b7f0ed0 | ||
|
|
056eadbef2 | ||
|
|
2bb2dc9040 | ||
|
|
17553fd412 | ||
|
|
08c1c0f682 | ||
|
|
84959ae9c9 | ||
|
|
c90c102097 | ||
|
|
5b004426ce | ||
|
|
69c9060dd2 | ||
|
|
49870639ff | ||
|
|
0843862af9 |
@@ -1,42 +1,5 @@
|
||||
---
|
||||
BasedOnStyle: Google
|
||||
AccessModifierOffset: 0
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignEscapedNewlines: Right
|
||||
AlignTrailingComments: true
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakConstructorInitializers: AfterColon
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
FixNamespaceComments: false
|
||||
IncludeBlocks: Preserve
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 3
|
||||
IndentAccessModifiers: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SpaceAfterCStyleCast: false
|
||||
---
|
||||
BasedOnStyle: WebKit
|
||||
BreakBeforeBraces: Attach
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
ColumnLimit: 0
|
||||
...
|
||||
|
||||
42
.github/workflows/cmake-linux.yml
vendored
Normal file
42
.github/workflows/cmake-linux.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: CMake Linux Build
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
linux-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Restore artifacts, or run vcpkg, build and cache artifacts
|
||||
uses: lukka/run-vcpkg@v7
|
||||
id: runvcpkg
|
||||
with:
|
||||
vcpkgArguments: 'zlib nlohmann-json openssl cpp-httplib[openssl]'
|
||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||
vcpkgGitCommitId: '40616a5e954f7be1077ef37db3fbddbd5dcd1ca6'
|
||||
|
||||
- name: Create Build Environment
|
||||
run: cmake -E make_directory ${{github.workspace}}/build-linux
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
working-directory: ${{github.workspace}}/build-linux
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE='${{ runner.workspace }}/b/vcpkg/scripts/buildsystems/vcpkg.cmake'
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build-linux
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: BeamMP-Launcher
|
||||
path: ${{github.workspace}}/build-linux/BeamMP-Launcher
|
||||
12
.github/workflows/cmake-windows.yml
vendored
12
.github/workflows/cmake-windows.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: CMake Windows Build
|
||||
|
||||
on: [push, pull_request]
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
@@ -12,15 +12,15 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
submodules: 'true'
|
||||
|
||||
- name: Restore artifacts, or run vcpkg, build and cache artifacts
|
||||
uses: lukka/run-vcpkg@v7
|
||||
id: runvcpkg
|
||||
with:
|
||||
vcpkgArguments: 'zlib discord-rpc nlohmann-json openssl minhook'
|
||||
vcpkgArguments: 'discord-rpc zlib nlohmann-json openssl cpp-httplib[openssl]'
|
||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||
vcpkgGitCommitId: '06b5f4a769d848d1a20fa0acd556019728b56273'
|
||||
vcpkgGitCommitId: '40616a5e954f7be1077ef37db3fbddbd5dcd1ca6'
|
||||
vcpkgTriplet: 'x64-windows-static'
|
||||
|
||||
- name: Create Build Environment
|
||||
@@ -34,10 +34,10 @@ jobs:
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build-windows
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target BeamMP-Launcher
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: BeamMP-Launcher.exe
|
||||
path: ${{github.workspace}}/build-windows/Release/BeamMP-Launcher.exe
|
||||
|
||||
72
.github/workflows/release-build.yml
vendored
72
.github/workflows/release-build.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: Release Create & Build
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
name: Create Release
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
steps:
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: |
|
||||
Files included in this release:
|
||||
- `BeamMP-Launcher.exe` windows build
|
||||
|
||||
upload-release-files-windows:
|
||||
name: Upload Windows Release Files
|
||||
runs-on: windows-latest
|
||||
needs: create-release
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Restore artifacts, or run vcpkg, build and cache artifacts
|
||||
uses: lukka/run-vcpkg@main
|
||||
id: runvcpkg
|
||||
with:
|
||||
vcpkgArguments: 'zlib discord-rpc nlohmann-json openssl minhook'
|
||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||
vcpkgGitCommitId: '06b5f4a769d848d1a20fa0acd556019728b56273'
|
||||
vcpkgTriplet: 'x64-windows-static'
|
||||
|
||||
- name: Create Build Environment
|
||||
run: cmake -E make_directory ${{github.workspace}}/build-windows
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
working-directory: ${{github.workspace}}/build-windows
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE='${{ runner.workspace }}/b/vcpkg/scripts/buildsystems/vcpkg.cmake' -DVCPKG_TARGET_TRIPLET=x64-windows-static
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build-windows
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target BeamMP-Launcher
|
||||
|
||||
- name: Upload Release Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||
asset_path: ${{github.workspace}}/build-windows/Release/BeamMP-Launcher.exe
|
||||
asset_name: BeamMP-Launcher.exe
|
||||
asset_content_type: application/vnd.microsoft.portable-executable
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -4,4 +4,11 @@ cmake-build-release
|
||||
*.log
|
||||
/*.sh
|
||||
/*.obj
|
||||
/*.exe
|
||||
/*.exe
|
||||
.cache/
|
||||
.https_debug/
|
||||
Launcher.cfg
|
||||
Resources/
|
||||
bin/
|
||||
compile_commands.json
|
||||
key
|
||||
|
||||
15
.gitmodules
vendored
15
.gitmodules
vendored
@@ -1,12 +1,3 @@
|
||||
[submodule "wxWidgets"]
|
||||
path = include/wxWidgets
|
||||
url = https://github.com/wxWidgets/wxWidgets.git
|
||||
[submodule "include/cpp-httplib"]
|
||||
path = include/cpp-httplib
|
||||
url = https://github.com/yhirose/cpp-httplib.git
|
||||
[submodule "include/tomlplusplus"]
|
||||
path = include/tomlplusplus
|
||||
url = https://github.com/marzer/tomlplusplus.git
|
||||
[submodule "include/easyloggingpp"]
|
||||
path = include/easyloggingpp
|
||||
url = https://github.com/amrayn/easyloggingpp.git
|
||||
[submodule "evpp"]
|
||||
path = evpp
|
||||
url = https://github.com/BeamMP/evpp.git
|
||||
|
||||
@@ -1,62 +1,39 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(BeamMP-Launcher)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(Launcher)
|
||||
|
||||
if (WIN32)
|
||||
message(STATUS "MSVC -> forcing use of statically-linked runtime.")
|
||||
STRING(REPLACE "/MD" "/MT /MP" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
|
||||
STRING(REPLACE "/MD" "/MT /MP" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
|
||||
STRING(REPLACE "/MDd" "/MTd /MP" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
STRING(REPLACE "/MDd" "/MTd /MP" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(minhook CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
#-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
|
||||
set(VcpkgRoot ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET})
|
||||
include_directories(${VcpkgRoot}/include)
|
||||
link_directories(${VcpkgRoot}/lib)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE")
|
||||
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
|
||||
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
endif(WIN32)
|
||||
|
||||
add_subdirectory(include/cpp-httplib)
|
||||
add_subdirectory(include/tomlplusplus)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
src/main.cpp include/easyloggingpp/src/easylogging++.cc
|
||||
src/Launcher.cpp include/Launcher.h include/Memory/Hook.h
|
||||
src/Memory/Definitions.cpp include/Memory/Definitions.h
|
||||
src/Memory/Memory.cpp include/Memory/Memory.h include/Memory/Patterns.h
|
||||
src/Memory/BeamNG.cpp include/Memory/BeamNG.h
|
||||
src/Memory/GELua.cpp include/Memory/GELua.h
|
||||
src/Memory/IPC.cpp include/Memory/IPC.h
|
||||
src/Logger.cpp include/Logger.h
|
||||
#src/gui/Gui.cpp
|
||||
include/Json.h include/hashpp.h
|
||||
src/Network/HttpAPI.cpp include/HttpAPI.h
|
||||
src/Network/Server.cpp include/Server.h
|
||||
src/Network/Login.cpp src/Network/Update.cpp
|
||||
src/Network/Compressor.cpp include/Compressor.h
|
||||
src/Handler.cpp src/Network/Resources.cpp
|
||||
src/Discord.cpp src/Config.cpp
|
||||
)
|
||||
add_compile_definitions(CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
|
||||
file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "src/*/*.hpp" "include/*.h" "include/*/*.h" "include/*/*/*.h" "include/*.hpp" "include/*/*.hpp" "include/*/*/*.hpp")
|
||||
find_package(httplib CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${source_files})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Launcher")
|
||||
|
||||
if (WIN32)
|
||||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE discord-rpc)
|
||||
endif()
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32
|
||||
Dbghelp comsuppw minhook::minhook nlohmann_json nlohmann_json::nlohmann_json)
|
||||
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32 httplib::httplib nlohmann_json::nlohmann_json)
|
||||
elseif (LINUX)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto)
|
||||
else(WIN32) #MINGW
|
||||
add_definitions("-D_WIN32_WINNT=0x0600")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -s --static")
|
||||
target_link_libraries(${PROJECT_NAME} discord-rpc ssl crypto ws2_32 ssp crypt32 z
|
||||
Dbghelp comsuppw minhook::minhook nlohmann_json nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(${PROJECT_NAME} ssl crypto ws2_32 ssp crypt32 z)
|
||||
endif(WIN32)
|
||||
add_definitions(-DELPP_NO_DEFAULT_LOG_FILE)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "include")
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "include/atomic_queue/include")
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# Contributing to BeamMP-Launcher
|
||||
|
||||
the BeamMP-Launcher might be affected by game updates depending on how major an update is.
|
||||
|
||||
To contribute *C++ code*, you'll need a MacOS, Linux or Windows PC, and intermediate to advanced knowledge of C++.
|
||||
For reference, you should know be reasonably comfortable with the STL, the concept of RAII, templates, and generally know how to read & write post-C++17 code. To contribute anything else, you won't need most of this (though it'd be helpful to have some vocabulary about computers).
|
||||
|
||||
# Ways to Contribute
|
||||
|
||||
## Bug Reports
|
||||
|
||||
If you work with the BeamMP-Launcher by simply using it, and you run into any issues, we definitely want to know about it. Please use [GitHub issues](https://github.com/BeamMP/BeamMP-Launcher/issues) and fill it out accordingly.
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
If you are interested in fixing bugs, check out the [GitHub issues](https://github.com/BeamMP/BeamMP-Launcher/issues). There, you can pick any issue that has nobody assigned to it. For example, some bugs which we definitely need some help with are marked with the "help wanted" tag.
|
||||
|
||||
Once you picked a bug, you need to reproduce it. Start by following the instructions in the bug report, and don't be afraid to ask for more information or clarification on the issue itself.
|
||||
|
||||
Refer to [getting started with the codebase](#getting-started-with-the-codebase) for more information on how to build the server. You can also ask on our [Discord server](https://discord.gg/beammp), or on IRC ([irc.libera.chat](https://web.libera.chat/), join `#beammp`).
|
||||
|
||||
## Features
|
||||
|
||||
If you want to add new features, please make an issue for it first or ask on our [Discord server](https://discord.gg/beammp), or on IRC ([irc.libera.chat](https://web.libera.chat/), join `#beammp`).
|
||||
|
||||
You need to make sure the feature isn't being worked on by someone else, and aligns with the vision we have for the launcher.
|
||||
|
||||
# Git Guidelines
|
||||
|
||||
**Read this carefully. Failing to follow these rules results in your changes not being accepted**. This applies for outside contributors, members of the BeamMP development team ("BeamMP Developers"), project owners, maintainers, frequent contributors, and literally everyone else. **It applies to everyone**.
|
||||
|
||||
## How to Commit
|
||||
|
||||
Commit messages **MUST** (mandatory):
|
||||
|
||||
- start with a **lower case action verb in present tense**, for example `add`, `fix`, `implement`, `refactor`, `remove`, `rename`. *Counter examples (these are bad): ~~`Fixed`, `fixing`, `added`, `removing`~~*.
|
||||
- not have a first line much longer than 70 characters.
|
||||
- explain briefly the changes made.
|
||||
- reference the issue by number, if there is an issue the commit addresses, like so: `#<number>`. Example: `#123`.
|
||||
|
||||
If any of these are not followed, **your changes will not be accepted.**
|
||||
|
||||
Commit messages **SHOULD** (optional, "nice to have"):
|
||||
|
||||
- only address one "atomic" change.
|
||||
- have an empty second line, and the subsequent lines explaining the changes in more detail (if more detail is available).
|
||||
|
||||
Commits may be squashed (via a Git "interactive rebase") in order to satisfy these rules, but history that is >1h old should not be rewritten if possible. Force pushes are ugly ;)
|
||||
|
||||
## Branches
|
||||
|
||||
### Which branch should I base my work on?
|
||||
|
||||
Each *feature* or *bug-fix* is implemented on a new Git branch, branched off of the branch it should be based on. The `master` branch is usually stable, so we don't do development on it. It is always a safe bet to branch off of `master`, but it may be more work to merge later. Branches to base your work on are typically branches like `v3`, when the latest public version is `3.2.0`, for example. These can often be found in Pull-Requests on GitHub.
|
||||
|
||||
### What should I call by branch?
|
||||
|
||||
Keep branch names **unique**, **descriptive**, and **shorter than 30 characters**. Names must be in present-tense, such as `fix-xyz`, **not** ~~`fixing-xyz`~~.
|
||||
|
||||
For example:
|
||||
- You want to fix issue number #123? You could call the branch `fix-123`.
|
||||
- You want to add a feature described in issue #456? You could call the branch `implement-456`.
|
||||
- You want to add a feature or fix a bug that has no issue? You should probably make an issue for it first! Or, if you're not ready for that yet, you could call it by the feature name or bug description, for example for a bug that makes cars disappear: `fix-disappearing-cars`.
|
||||
|
||||
## Pull Requests, Code Review
|
||||
|
||||
Once you are ready to show what you did, and get feedback on it, you open a Pull-Request on GitHub. Please make sure to pick the right branches, and a descriptive title. Mention any related issues with `#<issue number>`, for example `#123`.
|
||||
|
||||
Make sure to explain what the PR does, what it fixes, and what needs to still be done (if anything).
|
||||
|
||||
A BeamMP-Developer must review your code in detail, and leave a review. If this takes too long, feel free to @ a maintainer/developer, or leave another comment on the PR. It helps to say something like "Ready for review", for example.
|
||||
|
||||
# Getting Started with the Codebase
|
||||
|
||||
1. Look at current Pull-Requests, look at the git branches, or ask in our [Discord server](https://discord.gg/beammp), or on IRC ([irc.libera.chat](https://web.libera.chat/), join `#beammp`), in order to find out which branch you should work on to minimize conflict. See [this section on branches](#branches) for more info.
|
||||
2. Fork the repository (with that branch) on GitHub. GitHub, by default, gives you only the `master` branch when forking, so make sure you fork with other branches enabled when you want to work on a branch that isn't master (it's a checkbox when you fork).
|
||||
3. Clone the fork to your local machine.
|
||||
4. Check out the branch you want to work on (see 1.).
|
||||
5. Run `git submodule update --init --recursive`.
|
||||
6. Make a new branch for your feature or fix from the branch you are on. You can do this via `git checkout -b <branch name>`. See [this section on branches](#branches) for more info on branch naming.
|
||||
7. Install all dependencies. Those are usually listed in the `README.md` in the branch you're in, or, more reliably, in one of the files in `.github/workflows` (if you can read `yaml`).
|
||||
8. Run CMake to configure the project. You can find tutorials on this online. You will want to tell CMake to build with `CMAKE_BUILD_TYPE=Debug`, for example by passing it to CMake via the commandline switch `-DCMAKE_BUILD_TYPE=Debug`. An example invocation on Linux with GNU make would be
|
||||
`cmake . -DCMAKE_BUILD_TYPE=Debug` .
|
||||
9. Build the `BeamMP-Launcher` target to build the BeamMP-Launcher. In the example from 8. (on Linux), you could build with `make BeamMP-Server`, `make -j BeamMP-Server` or `cmake --build . --parallel --target BeamMP-Server` . Or, on Windows, (in Visual Studio), you would just press some big green "run" or "debug" button, it is advised to use CLion on Windows.
|
||||
10. When making changes, refer to [this section on how to commit properly](#how-to-commit). Not following those guidelines will result in your changes being rejected, so please take a look.
|
||||
|
||||
# Code Guidelines
|
||||
|
||||
## Formatting
|
||||
|
||||
1. Use `clang-format` to format your code before committing. A `.clang-format` file is provided in the root of the repository.
|
||||
2. All identifiers, type names, function names, etc. should be `PascalCase`.
|
||||
|
||||
## Modular code
|
||||
|
||||
Write code that is modular and testable. Generally, if you can write a good unit-test for it, it's modular. If you can't, it's not.
|
||||
|
||||
Don't overdo it though - sometimes it is okay to just write code, do the job, be done with it. You'll get feedback on this in the code review for your PR.
|
||||
2
LICENSE
2
LICENSE
@@ -1,2 +0,0 @@
|
||||
Copyright (c) 2019-present BeamMP LTD, BeamMP-Launcher code is not in the public domain and is not free software. One must be granted explicit permission by the copyright holder(s) in order to modify or distribute any part of the source or binaries. Special permission to modify the source-code is implicitly granted only for the purpose of upstreaming those changes directly to github.com/BeamMP/BeamMP-Launcher via a GitHub pull-request.
|
||||
Commercial usage is prohibited, unless explicit permission has been granted prior to usage.
|
||||
35
README.md
35
README.md
@@ -1,24 +1,27 @@
|
||||
# BeamMP-Launcher
|
||||
|
||||
The launcher is the way we communicate to servers, it does a few automated actions such as but not limited to:
|
||||
downloading the mod, launching the game, and establishing server connections.
|
||||
The launcher is the way we communitcate to outside the game, it does a few automated actions such as but not limited to: downloading the mod, launching the game, and create a connection to a server.
|
||||
|
||||
**To clone this repository**: `git clone --recurse-submodules https://github.com/BeamMP/BeamMP-Launcher.git`
|
||||
|
||||
# Dependencies
|
||||
## How to build - Release
|
||||
|
||||
it is recommended to use vcpkg and link it to clion or your cmake project via the cmake options using `-DCMAKE_TOOLCHAIN_FILE=PATH_VCPKG/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static`
|
||||
notice how we specify the target being windows-static you need to install the `static` versions of these dependencies.
|
||||
In the root directory of the project,
|
||||
1. `cmake -DCMAKE_BUILD_TYPE=Release . -B bin -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static`
|
||||
2. `cmake --build bin --parallel --config Release`
|
||||
|
||||
Remember to change `C:/vcpkg` to wherever you have vcpkg installed.
|
||||
|
||||
- [zlib](https://github.com/madler/zlib) for compression (might be soon removed)
|
||||
- [discord-rpc](https://github.com/discord/discord-rpc) for discord rich presence
|
||||
- [nlohmann-json](https://github.com/nlohmann/json) for reading and parsing JSON
|
||||
- [openssl](https://github.com/openssl/openssl) for secure networking
|
||||
- [minhook](https://github.com/TsudaKageyu/minhook) for function hooking
|
||||
## How to build - Debug
|
||||
|
||||
# Copyright
|
||||
In the root directory of the project,
|
||||
1. `cmake . -B bin -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static`
|
||||
2. `cmake --build bin --parallel`
|
||||
|
||||
Copyright (c) 2019-present BeamMP LTD,
|
||||
BeamMP-Launcher code is not in the public domain and is not free software.
|
||||
One must be granted explicit permission by the copyright holder(s) in order to modify or distribute any part of the source or binaries.
|
||||
Special permission to modify the source-code is implicitly granted only for the purpose of upstreaming those changes directly to github.com/BeamMP/BeamMP-Launcher via a GitHub pull-request.
|
||||
Commercial usage is prohibited, unless explicit permission has been granted prior to usage.
|
||||
Remember to change `C:/vcpkg` to wherever you have vcpkg installed.
|
||||
|
||||
Copyright (c) 2019-present Anonymous275.
|
||||
BeamMP Launcher code is not in the public domain and is not free software.
|
||||
One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries,
|
||||
the only permission that has been granted is to use the software in its compiled form as distributed from the BeamMP.com website.
|
||||
Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
|
||||
1
evpp
Submodule
1
evpp
Submodule
Submodule evpp added at 44e10774e2
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1,13 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/30/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class Zlib {
|
||||
public:
|
||||
static std::string DeComp(std::string Compressed);
|
||||
static std::string Comp(std::string Data);
|
||||
};
|
||||
21
include/Http.h
Normal file
21
include/Http.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 7/18/2020
|
||||
///
|
||||
#pragma once
|
||||
#include "Logger.h"
|
||||
#include <string>
|
||||
class HTTP {
|
||||
public:
|
||||
static bool Download(const std::string& IP, const std::string& Path);
|
||||
static std::string Post(const std::string& IP, const std::string& Fields);
|
||||
static std::string Get(const std::string& IP);
|
||||
static bool ProgressBar(size_t c, size_t t);
|
||||
static void StartProxy();
|
||||
public:
|
||||
static bool isDownload;
|
||||
static inline bool SkipSslVerify = false;
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/17/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
typedef bool (*DownloadProgress) (size_t c, size_t t);
|
||||
class HTTP {
|
||||
public:
|
||||
static bool Download(const std::string& IP, const std::string& Path, DownloadProgress DP = ProgressBar);
|
||||
static std::string Post(const std::string& IP, const std::string& Fields);
|
||||
static std::string Get(const std::string& IP, DownloadProgress DP = ProgressBar);
|
||||
static bool ProgressBar(size_t c, size_t t);
|
||||
|
||||
public:
|
||||
static bool isDownload;
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/16/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
using Json = nlohmann::json;
|
||||
@@ -1,107 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 12/26/21
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <filesystem>
|
||||
#include <thread>
|
||||
#include "Memory/IPC.h"
|
||||
#include "Server.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct VersionParser {
|
||||
explicit VersionParser(const std::string& from_string);
|
||||
std::strong_ordering operator<=>(VersionParser const& rhs) const noexcept;
|
||||
bool operator==(VersionParser const& rhs) const noexcept;
|
||||
std::vector<std::string> split;
|
||||
std::vector<size_t> data;
|
||||
};
|
||||
|
||||
struct HKEY__;
|
||||
typedef HKEY__* HKEY;
|
||||
|
||||
class Launcher {
|
||||
public: // constructors
|
||||
Launcher(int argc, char* argv[]);
|
||||
~Launcher();
|
||||
|
||||
public: // available functions
|
||||
static void StaticAbort(Launcher* Instance = nullptr);
|
||||
std::string Login(const std::string& fields);
|
||||
void UpdateKey(const std::string& newKey);
|
||||
void SendIPC(const std::string& Data, bool core = true);
|
||||
void LoadConfig(const fs::path& conf);
|
||||
void RunDiscordRPC();
|
||||
void UpdateCheck();
|
||||
void WaitForGame();
|
||||
void LaunchGame();
|
||||
void CheckKey();
|
||||
void SetupMOD();
|
||||
|
||||
static std::string QueryValue(HKEY& hKey, const char* Name);
|
||||
|
||||
public: // Getters and Setters
|
||||
void setDiscordMessage(const std::string& message);
|
||||
static void setExit(bool exit) noexcept;
|
||||
const std::string& getFullVersion();
|
||||
const fs::path& getMPUserPath();
|
||||
const fs::path& getCachePath();
|
||||
static bool Terminated() noexcept;
|
||||
const std::string& getPublicKey();
|
||||
const std::string& getUserRole();
|
||||
const std::string& getVersion();
|
||||
static bool getExit() noexcept;
|
||||
|
||||
private: // functions
|
||||
void HandleIPC(const std::string& Data);
|
||||
bool IsAllowedLink(const std::string& Link);
|
||||
std::string GetProfileVersion();
|
||||
fs::path GetProfileRoot();
|
||||
void UpdatePresence();
|
||||
void RichPresence();
|
||||
void WindowsInit();
|
||||
void ResetMods();
|
||||
void EnableMP();
|
||||
void ListenIPC();
|
||||
void Abort();
|
||||
|
||||
public: // variables
|
||||
static inline std::thread EntryThread{};
|
||||
static inline std::string Version{"2.1"};
|
||||
static inline std::string FullVersion{Version + ".1"};
|
||||
|
||||
private: // variables
|
||||
uint32_t GamePID{0};
|
||||
fs::path MPUserPath{};
|
||||
fs::path BeamUserPath{};
|
||||
fs::path BeamProfilePath{};
|
||||
fs::path LauncherCache{};
|
||||
int64_t DiscordTime{};
|
||||
bool LoginAuth = false;
|
||||
bool DebugMode = false;
|
||||
fs::path CurrentPath{};
|
||||
std::string BeamRoot{};
|
||||
std::string UserRole{};
|
||||
std::string PublicKey{};
|
||||
std::thread IPCSystem{};
|
||||
std::thread DiscordRPC{};
|
||||
std::string ConnectURI{};
|
||||
std::string BeamVersion{};
|
||||
std::string DiscordMessage{};
|
||||
Server ServerHandler{this};
|
||||
std::string TargetBuild{"default"};
|
||||
|
||||
static inline std::atomic<bool> Shutdown{false}, Exit{false};
|
||||
std::unique_ptr<IPC> IPCToGame{};
|
||||
std::unique_ptr<IPC> IPCFromGame{};
|
||||
};
|
||||
|
||||
class ShutdownException : public std::runtime_error {
|
||||
public:
|
||||
explicit ShutdownException(const std::string& message) :
|
||||
runtime_error(message){};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 12/26/21
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
/// Created by Anonymous275 on 4/2/2020.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <easyloggingpp/src/easylogging++.h>
|
||||
#undef min
|
||||
#undef max
|
||||
class Log {
|
||||
public:
|
||||
static void Init();
|
||||
static void ConsoleOutput(bool enable);
|
||||
private:
|
||||
static inline el::Configurations Conf{};
|
||||
};
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
void InitLog();
|
||||
void except(const std::string& toPrint);
|
||||
void fatal(const std::string& toPrint);
|
||||
void debug(const std::string& toPrint);
|
||||
void error(const std::string& toPrint);
|
||||
void info(const std::string& toPrint);
|
||||
void warn(const std::string& toPrint);
|
||||
std::string getDate();
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/21/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Memory/GELua.h"
|
||||
#include "Memory/Hook.h"
|
||||
#include "Memory/IPC.h"
|
||||
|
||||
class BeamNG {
|
||||
public:
|
||||
static void EntryPoint();
|
||||
static void SendIPC(const std::string& Data);
|
||||
static inline bool Terminate = false;
|
||||
private:
|
||||
static inline std::unique_ptr<Hook<def::update_function>> UpdateDetour;
|
||||
static inline std::unique_ptr<Hook<def::lua_open_jit>> OpenJITDetour;
|
||||
static inline std::unique_ptr<IPC> IPCFromLauncher;
|
||||
static inline std::unique_ptr<IPC> IPCToLauncher;
|
||||
static inline uint64_t GameBaseAddr;
|
||||
static inline uint64_t DllBaseAddr;
|
||||
static int lua_open_jit_D(lua_State* State);
|
||||
static uint64_t update_D(lua_State* State);
|
||||
static void RegisterGEFunctions();
|
||||
// static int GetTickCount_D(void* GEState, void* Param2, void* Param3, void*
|
||||
// Param4);
|
||||
static void IPCListener();
|
||||
static uint32_t IPCSender(void* LP);
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/27/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
typedef int (*lua_CFunction)(lua_State*);
|
||||
extern int lua_gettop(lua_State* L);
|
||||
namespace def {
|
||||
typedef int (*GEUpdate)(void* Param1, void* Param2, void* Param3,
|
||||
void* Param4);
|
||||
typedef uint32_t (*GetTickCount)();
|
||||
typedef int (*lua_open_jit)(lua_State* L);
|
||||
typedef uint64_t (*update_function)(lua_State* L);
|
||||
typedef void (*lua_get_field)(lua_State* L, int idx, const char* k);
|
||||
typedef const char* (*lua_push_fstring)(lua_State* L, const char* fmt, ...);
|
||||
typedef int (*lua_p_call)(lua_State* L, int arg, int res, int err);
|
||||
typedef void (*lua_pushcclosure)(lua_State* L, lua_CFunction fn, int n);
|
||||
typedef int (*lua_settop)(lua_State* L, int idx);
|
||||
typedef void (*lua_settable)(lua_State* L, int idx);
|
||||
typedef void (*lua_createtable)(lua_State* L, int narray, int nrec);
|
||||
typedef void (*lua_setfield)(lua_State* L, int idx, const char* k);
|
||||
typedef const char* (*lua_tolstring)(lua_State* L, int idx, size_t* len);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/30/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include "Definitions.h"
|
||||
|
||||
class GELua {
|
||||
public:
|
||||
static void FindAddresses();
|
||||
static inline def::GEUpdate GEUpdate;
|
||||
static inline def::lua_settop lua_settop;
|
||||
static inline def::GetTickCount GetTickCount;
|
||||
static inline def::lua_open_jit lua_open_jit;
|
||||
static inline def::update_function update_function;
|
||||
static inline def::lua_push_fstring lua_push_fstring;
|
||||
static inline def::lua_get_field lua_get_field;
|
||||
static inline def::lua_p_call lua_p_call;
|
||||
static inline def::lua_createtable lua_createtable;
|
||||
static inline def::lua_pushcclosure lua_pushcclosure;
|
||||
static inline def::lua_setfield lua_setfield;
|
||||
static inline def::lua_settable lua_settable;
|
||||
static inline def::lua_tolstring lua_tolstring;
|
||||
static inline lua_State* State;
|
||||
};
|
||||
|
||||
namespace GELuaTable {
|
||||
inline void Begin(lua_State* L) {
|
||||
GELua::lua_createtable(L, 0, 0);
|
||||
}
|
||||
inline void End(lua_State* L, const char* name) {
|
||||
GELua::lua_setfield(L, -10002, name);
|
||||
}
|
||||
inline void BeginEntry(lua_State* L, const char* name) {
|
||||
GELua::lua_push_fstring(L, "%s", name);
|
||||
}
|
||||
inline void EndEntry(lua_State* L) {
|
||||
GELua::lua_settable(L, -3);
|
||||
}
|
||||
inline void InsertFunction(lua_State* L, const char* name,
|
||||
lua_CFunction func) {
|
||||
//BeginEntry(L, name);
|
||||
GELua::lua_pushcclosure(L, func, 0);
|
||||
End(L, name);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/21/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <MinHook.h>
|
||||
#include "Memory/Memory.h"
|
||||
|
||||
#pragma once
|
||||
template<class FuncType>
|
||||
class Hook {
|
||||
FuncType targetPtr;
|
||||
FuncType detourFunc;
|
||||
bool Attached = false;
|
||||
|
||||
public:
|
||||
Hook(FuncType src, FuncType dest) : targetPtr(src), detourFunc(dest) {
|
||||
auto status =
|
||||
MH_CreateHook((void*)targetPtr, (void*)detourFunc, (void**)&Original);
|
||||
if (status != MH_OK) {
|
||||
Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Enable() {
|
||||
if (!Attached) {
|
||||
auto status = MH_EnableHook((void*)targetPtr);
|
||||
if (status != MH_OK) {
|
||||
Memory::Print(std::string("MH Error -> ") +
|
||||
MH_StatusToString(status));
|
||||
return;
|
||||
}
|
||||
Attached = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Disable() {
|
||||
if (Attached) {
|
||||
auto status = MH_DisableHook((void*)targetPtr);
|
||||
if (status != MH_OK) {
|
||||
Memory::Print(std::string("MH Error -> ") +
|
||||
MH_StatusToString(status));
|
||||
return;
|
||||
}
|
||||
Attached = false;
|
||||
}
|
||||
}
|
||||
|
||||
FuncType Original{};
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/26/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class IPC {
|
||||
public:
|
||||
IPC() = default;
|
||||
IPC(uint32_t ID, size_t Size) noexcept;
|
||||
[[nodiscard]] size_t size() const noexcept;
|
||||
[[nodiscard]] char* c_str() const noexcept;
|
||||
void send(const std::string& msg) noexcept;
|
||||
[[nodiscard]] void* raw() const noexcept;
|
||||
[[nodiscard]] bool receive_timed_out() const noexcept;
|
||||
[[nodiscard]] bool send_timed_out() const noexcept;
|
||||
const std::string& msg() noexcept;
|
||||
void confirm_receive() noexcept;
|
||||
void try_receive() noexcept;
|
||||
void receive() noexcept;
|
||||
~IPC() noexcept;
|
||||
static bool mem_used(uint32_t MemID) noexcept;
|
||||
|
||||
private:
|
||||
void* SemConfHandle_;
|
||||
void* MemoryHandle_;
|
||||
void* SemHandle_;
|
||||
std::string Msg_;
|
||||
bool SendTimeout;
|
||||
bool RcvTimeout;
|
||||
size_t Size_;
|
||||
char* Data_;
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/21/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
class Memory {
|
||||
public:
|
||||
static uint64_t FindPattern(const char* module, const char* Pattern[]);
|
||||
static uint32_t GetBeamNGPID(const std::set<uint32_t>& BL);
|
||||
static uint32_t GetLauncherPID(const std::set<uint32_t>& BL);
|
||||
static uint64_t GetModuleBase(const char* Name);
|
||||
static void Print(const std::string& msg);
|
||||
static std::string GetHex(uint64_t num);
|
||||
static inline bool DebugMode = false;
|
||||
static void Inject(uint32_t PID);
|
||||
static uint32_t GetTickCount();
|
||||
static uint32_t EntryPoint();
|
||||
static uint32_t GetPID();
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/21/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
namespace Patterns {
|
||||
const char* GetTickCount[2]{
|
||||
"\x48\xff\x25\x00\x00\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48"
|
||||
"\x83\xec\x00\x48\x8d\x4c\x24",
|
||||
"xxx????xxxxxxxxxxxx?xxxx"};
|
||||
const char* open_jit[2]{
|
||||
"\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b"
|
||||
"\x05\x00\x00\x00\x00\x48\x33\xc4\x48\x89\x44\x24\x00\x48\x8b\x71\x00"
|
||||
"\x48\x8d\x54\x24",
|
||||
"xxxx?xxxx?xxxx?xxx????xxxxxxx?xxx?xxxx"};
|
||||
const char* get_field[2]{
|
||||
"\x48\x89\x5c\x24\x00\x57\x48\x83\xec\x00\x4d\x8b\xd0\x48\x8b\xd9\xe8"
|
||||
"\x00\x00\x00\x00\x48\x8b\xf8\x49\xc7\xc0\x00\x00\x00\x00\x90\x49\xff"
|
||||
"\xc0\x43\x80\x3c\x02\x00\x75\x00\x49\x8b\xd2\x48\x8b\xcb\xe8\x00\x00"
|
||||
"\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x8d\x44\x24\x00"
|
||||
"\x48\x0b\xc1\x48\x8b\xd7\x48\x8b\xcb\x48\x89\x44\x24\x00\xe8\x00\x00"
|
||||
"\x00\x00\x48\x85\xc0",
|
||||
"xxxx?xxxx?xxxxxxx????xxxxxx????xxxxxxxx?x?xxxxxxx????xx????????xxxx?"
|
||||
"xxxxxxxxxxxxx?x????xxx"};
|
||||
const char* push_fstring[2]{
|
||||
"\x48\x89\x54\x24\x00\x4c\x89\x44\x24\x00\x4c\x89\x4c\x24\x00\x53\x48"
|
||||
"\x83\xec\x00\x4c\x8b\x41",
|
||||
"xxxx?xxxx?xxxx?xxxx?xxx"};
|
||||
const char* p_call[2]{
|
||||
"\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b"
|
||||
"\x59\x00\x41\x8b\xf0\x4c\x63\xda",
|
||||
"xxxx?xxxx?xxxx?xxx?xxxxxx"};
|
||||
const char* lua_setfield[2]{
|
||||
"\x48\x89\x5c\x24\x00\x57\x48\x83\xec\x00\x4d\x8b\xd0\x48\x8b\xd9\xe8"
|
||||
"\x00\x00\x00\x00\x48\x8b\xf8\x49\xc7\xc0\x00\x00\x00\x00\x90\x49\xff"
|
||||
"\xc0\x43\x80\x3c\x02\x00\x75\x00\x49\x8b\xd2\x48\x8b\xcb\xe8\x00\x00"
|
||||
"\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4c\x8d\x44\x24\x00"
|
||||
"\x48\x0b\xc1\x48\x8b\xd7\x48\x8b\xcb\x48\x89\x44\x24\x00\xe8\x00\x00"
|
||||
"\x00\x00\x48\x8b\x53",
|
||||
"xxxx?xxxx?xxxxxxx????xxxxxx????xxxxxxxx?x?xxxxxxx????xx????????xxxx?"
|
||||
"xxxxxxxxxxxxx?x????xxx"};
|
||||
const char* lua_createtable[2]{
|
||||
"\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x4c\x8b"
|
||||
"\x49\x00\x41\x8b\xf8",
|
||||
"xxxx?xxxx?xxxx?xxx?xxx"};
|
||||
const char* lua_settable[2]{
|
||||
"\x40\x53\x48\x83\xec\x00\x48\x8b\xd9\xe8\x00\x00\x00\x00\x4c\x8b\x43"
|
||||
"\x00\x48\x8b\xd0\x49\x83\xe8\x00\x48\x8b\xcb\xe8\x00\x00\x00\x00\x48"
|
||||
"\x8b\x53",
|
||||
"xxxxx?xxxx????xxx?xxxxxx?xxxx????xxx"};
|
||||
const char* lua_pushcclosure[2]{
|
||||
"\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x48\x8b"
|
||||
"\xd9\x49\x63\xf8\x48\x8b\x49\x00\x48\x8b\xf2",
|
||||
"xxxx?xxxx?xxxx?xxxxxxxxx?xxx"};
|
||||
const char* lua_tolstring[2]{
|
||||
"\x48\x89\x5c\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xec\x00\x49\x8b"
|
||||
"\xf8\x8b\xda\x48\x8b\xf1\xe8",
|
||||
"xxxx?xxxx?xxxx?xxxxxxxxx"};
|
||||
const char* GEUpdate[2]{
|
||||
"\x48\x89\x5c\x24\x00\x48\x89\x6c\x24\x00\x56\x57\x41\x56\x48\x83\xec"
|
||||
"\x00\x4c\x8b\x31\x49\x8b\xf0",
|
||||
"xxxx?xxxx?xxxxxxx?xxxxxx"};
|
||||
const char* lua_settop[2]{
|
||||
"\x4c\x8b\xc1\x85\xd2\x7e\x00\x48\x8b\x41\x00\x48\x8b\x49",
|
||||
"xxxxxx?xxx?xxx"};
|
||||
const char* update_function[2] {
|
||||
"\x48\x89\x4c\x24\x00\x48\x83\xec\x00\xba\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x48\x8b\x48",
|
||||
"xxxx?xxx?x????x????xxx"
|
||||
};
|
||||
}
|
||||
56
include/Network/network.hpp
Normal file
56
include/Network/network.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 7/18/2020
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#ifdef __linux__
|
||||
#include "linuxfixes.h"
|
||||
#include <bits/types/siginfo_t.h>
|
||||
#include <cstdint>
|
||||
#include <sys/ucontext.h>
|
||||
#endif
|
||||
|
||||
void NetReset();
|
||||
extern bool Dev;
|
||||
extern int ping;
|
||||
|
||||
[[noreturn]] void CoreNetwork();
|
||||
extern int ProxyPort;
|
||||
extern int ClientID;
|
||||
extern int LastPort;
|
||||
extern bool ModLoaded;
|
||||
extern bool Terminate;
|
||||
extern int DEFAULT_PORT;
|
||||
extern uint64_t UDPSock;
|
||||
extern uint64_t TCPSock;
|
||||
extern std::string Branch;
|
||||
extern std::string CachingDirectory;
|
||||
extern bool TCPTerminate;
|
||||
extern std::string LastIP;
|
||||
extern std::string MStatus;
|
||||
extern std::string UlStatus;
|
||||
extern std::string PublicKey;
|
||||
extern std::string PrivateKey;
|
||||
int KillSocket(uint64_t Dead);
|
||||
void UUl(const std::string& R);
|
||||
void UDPSend(std::string Data);
|
||||
bool CheckBytes(int32_t Bytes);
|
||||
void GameSend(std::string_view Data);
|
||||
void SendLarge(std::string Data);
|
||||
std::string TCPRcv(uint64_t Sock);
|
||||
void SyncResources(uint64_t TCPSock);
|
||||
std::string GetAddr(const std::string& IP);
|
||||
void ServerParser(std::string_view Data);
|
||||
std::string Login(const std::string& fields);
|
||||
void TCPSend(const std::string& Data, uint64_t Sock);
|
||||
void TCPClientMain(const std::string& IP, int Port);
|
||||
void UDPClientMain(const std::string& IP, int Port);
|
||||
void TCPGameServer(const std::string& IP, int Port);
|
||||
bool SecurityWarning();
|
||||
void CoreSend(std::string data);
|
||||
9
include/Security/Game.h
Normal file
9
include/Security/Game.h
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 7/19/2020
|
||||
///
|
||||
#pragma once
|
||||
extern unsigned long GamePID;
|
||||
15
include/Security/Init.h
Normal file
15
include/Security/Init.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 7/18/2020
|
||||
///
|
||||
#pragma once
|
||||
#include <string>
|
||||
void PreGame(const std::string& GamePath);
|
||||
std::string CheckVer(const std::string& path);
|
||||
void InitGame(const std::string& Dir);
|
||||
std::string GetGameDir();
|
||||
void LegitimacyCheck();
|
||||
void CheckLocalKey();
|
||||
@@ -1,78 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/30/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
struct sockaddr_in;
|
||||
class Launcher;
|
||||
class Server {
|
||||
public:
|
||||
Server() = delete;
|
||||
explicit Server(Launcher* Instance);
|
||||
~Server();
|
||||
|
||||
public:
|
||||
void ServerSend(std::string Data, bool Rel);
|
||||
void Connect(const std::string& Data);
|
||||
const std::string& getModList();
|
||||
const std::string& getUIStatus();
|
||||
const std::string& getMap();
|
||||
void StartUDP();
|
||||
void setModLoaded();
|
||||
bool Terminated();
|
||||
int getPing() const;
|
||||
void Close();
|
||||
|
||||
private:
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> PingStart,
|
||||
PingEnd;
|
||||
std::string MultiDownload(uint64_t DSock, uint64_t Size,
|
||||
const std::string& Name);
|
||||
void AsyncUpdate(uint64_t& Rcv, uint64_t Size, const std::string& Name);
|
||||
std::atomic<bool> Terminate{false}, ModLoaded{false};
|
||||
char* TCPRcvRaw(uint64_t Sock, uint64_t& GRcv, uint64_t Size);
|
||||
std::string GetAddress(const std::string& Data);
|
||||
void InvalidResource(const std::string& File);
|
||||
void UpdateUl(bool D, const std::string& msg);
|
||||
std::unique_ptr<sockaddr_in> UDPSockAddress;
|
||||
void ServerParser(const std::string& Data);
|
||||
static std::string GetSocketApiError();
|
||||
void TCPSend(const std::string& Data);
|
||||
void UDPParser(std::string Packet);
|
||||
void SendLarge(std::string Data);
|
||||
void UDPSend(std::string Data);
|
||||
void UUl(const std::string& R);
|
||||
bool CheckBytes(int32_t Bytes);
|
||||
int KillSocket(uint64_t Dead);
|
||||
void MultiKill(uint64_t Sock);
|
||||
Launcher* LauncherInstance;
|
||||
std::thread TCPConnection;
|
||||
std::thread UDPConnection;
|
||||
std::thread AutoPing;
|
||||
uint64_t TCPSocket = -1;
|
||||
uint64_t UDPSocket = -1;
|
||||
void WaitForConfirm();
|
||||
std::string UStatus{};
|
||||
std::string MStatus{};
|
||||
std::string ModList{};
|
||||
void TCPClientMain();
|
||||
void SyncResources();
|
||||
std::string TCPRcv();
|
||||
uint64_t InitDSock();
|
||||
std::string Auth();
|
||||
std::string IP{};
|
||||
void UDPClient();
|
||||
void PingLoop();
|
||||
int ClientID{0};
|
||||
void UDPMain();
|
||||
void UDPRcv();
|
||||
void Abort();
|
||||
int Port{0};
|
||||
int Ping{0};
|
||||
};
|
||||
21
include/Startup.h
Normal file
21
include/Startup.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 7/18/2020
|
||||
///
|
||||
#pragma once
|
||||
#include <compare>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
void InitLauncher(int argc, char* argv[]);
|
||||
std::string GetEP(char* P = nullptr);
|
||||
std::string GetGamePath();
|
||||
std::string GetVer();
|
||||
std::string GetPatch();
|
||||
std::string GetEN();
|
||||
void ConfigInit();
|
||||
extern bool Dev;
|
||||
|
||||
20
include/Utils.h
Normal file
20
include/Utils.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Utils {
|
||||
inline std::vector<std::string> Split(const std::string& String, const std::string& delimiter) {
|
||||
std::vector<std::string> Val;
|
||||
size_t pos;
|
||||
std::string token, s = String;
|
||||
while ((pos = s.find(delimiter)) != std::string::npos) {
|
||||
token = s.substr(0, pos);
|
||||
if (!token.empty())
|
||||
Val.push_back(token);
|
||||
s.erase(0, pos + delimiter.length());
|
||||
}
|
||||
if (!s.empty())
|
||||
Val.push_back(s);
|
||||
return Val;
|
||||
};
|
||||
};
|
||||
13
include/Zlib/Compressor.h
Normal file
13
include/Zlib/Compressor.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2019-present Anonymous275.
|
||||
// BeamMP Launcher code is not in the public domain and is not free software.
|
||||
// One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries.
|
||||
// Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
||||
///
|
||||
/// Created by Anonymous275 on 7/24/2020
|
||||
///
|
||||
#pragma once
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
std::vector<char> Comp(std::span<const char> input);
|
||||
std::vector<char> DeComp(std::span<const char> input);
|
||||
@@ -1,57 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 7/26/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#pragma once
|
||||
#include <queue>
|
||||
#include <semaphore>
|
||||
|
||||
template<class T, size_t Size>
|
||||
class atomic_queue {
|
||||
public:
|
||||
bool try_pop(T& val) {
|
||||
lock_guard guard(semaphore);
|
||||
if (queue.empty()) return false;
|
||||
val = queue.front();
|
||||
queue.pop();
|
||||
full.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
void push(const T& val) {
|
||||
check_full();
|
||||
lock_guard guard(semaphore);
|
||||
queue.push(val);
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
lock_guard guard(semaphore);
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
lock_guard guard(semaphore);
|
||||
return queue.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
void check_full() {
|
||||
if (size() >= Size) {
|
||||
full.acquire();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct lock_guard {
|
||||
explicit lock_guard(std::binary_semaphore& lock) : lock(lock) {
|
||||
lock.acquire();
|
||||
}
|
||||
~lock_guard() { lock.release(); }
|
||||
|
||||
private:
|
||||
std::binary_semaphore& lock;
|
||||
};
|
||||
std::binary_semaphore semaphore{1}, full{0};
|
||||
std::queue<T> queue{};
|
||||
};
|
||||
Submodule include/cpp-httplib deleted from fee8e97b4e
Submodule include/easyloggingpp deleted from 8489989bb2
8836
include/hashpp.h
8836
include/hashpp.h
File diff suppressed because it is too large
Load Diff
19
include/linuxfixes.h
Normal file
19
include/linuxfixes.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef _LINUXFIXES_H
|
||||
#define _LINUXFIXES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Translate windows sockets stuff to linux sockets
|
||||
#define SOCKET uint64_t
|
||||
#define SOCKADDR sockaddr
|
||||
#define SOCKADDR_IN sockaddr_in
|
||||
#define WSAGetLastError() errno
|
||||
#define closesocket close
|
||||
#define SD_BOTH SHUT_RDWR
|
||||
// We dont need wsacleanup
|
||||
#define WSACleanup()
|
||||
#define SOCKET_ERROR -1
|
||||
|
||||
#define ZeroMemory(mem, len) memset(mem, 0, len)
|
||||
|
||||
#endif
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lauxlib_h
|
||||
#define lauxlib_h
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
/* extra error code for `luaL_load' */
|
||||
#define LUA_ERRFILE (LUA_ERRERR+1)
|
||||
|
||||
typedef struct luaL_Reg {
|
||||
const char *name;
|
||||
lua_CFunction func;
|
||||
} luaL_Reg;
|
||||
|
||||
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
|
||||
const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
|
||||
const luaL_Reg *l);
|
||||
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
|
||||
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
|
||||
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
|
||||
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
|
||||
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
|
||||
size_t *l);
|
||||
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
|
||||
const char *def, size_t *l);
|
||||
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
|
||||
|
||||
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
|
||||
lua_Integer def);
|
||||
|
||||
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
|
||||
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
|
||||
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
|
||||
|
||||
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
|
||||
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
|
||||
|
||||
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
|
||||
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
|
||||
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
|
||||
const char *const lst[]);
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
LUALIB_API int (luaL_ref) (lua_State *L, int t);
|
||||
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
|
||||
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
|
||||
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name);
|
||||
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
|
||||
|
||||
LUALIB_API lua_State *(luaL_newstate) (void);
|
||||
|
||||
|
||||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
|
||||
const char *r);
|
||||
|
||||
LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
|
||||
const char *fname, int szhint);
|
||||
|
||||
/* From Lua 5.2. */
|
||||
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
|
||||
LUALIB_API int luaL_execresult(lua_State *L, int stat);
|
||||
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name, const char *mode);
|
||||
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
||||
int level);
|
||||
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
|
||||
int sizehint);
|
||||
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
|
||||
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define luaL_argcheck(L, cond,numarg,extramsg) \
|
||||
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
|
||||
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
|
||||
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
|
||||
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
|
||||
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
|
||||
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
|
||||
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
|
||||
|
||||
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
|
||||
|
||||
#define luaL_dofile(L, fn) \
|
||||
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
#define luaL_dostring(L, s) \
|
||||
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
|
||||
|
||||
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
|
||||
|
||||
/* From Lua 5.2. */
|
||||
#define luaL_newlibtable(L, l) \
|
||||
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
|
||||
#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
typedef struct luaL_Buffer {
|
||||
char *p; /* current position in buffer */
|
||||
int lvl; /* number of strings in the stack (level) */
|
||||
lua_State *L;
|
||||
char buffer[LUAL_BUFFERSIZE];
|
||||
} luaL_Buffer;
|
||||
|
||||
#define luaL_addchar(B,c) \
|
||||
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
|
||||
(*(B)->p++ = (char)(c)))
|
||||
|
||||
/* compatibility only */
|
||||
#define luaL_putchar(B,c) luaL_addchar(B,c)
|
||||
|
||||
#define luaL_addsize(B,n) ((B)->p += (n))
|
||||
|
||||
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
|
||||
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
|
||||
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
|
||||
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
|
||||
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
|
||||
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
|
||||
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
#endif
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
** Bundled memory allocator.
|
||||
** Donated to the public domain.
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ALLOC_H
|
||||
#define _LJ_ALLOC_H
|
||||
|
||||
#include "lj_def.h"
|
||||
|
||||
#ifndef LUAJIT_USE_SYSMALLOC
|
||||
LJ_FUNC void *lj_alloc_create(void);
|
||||
LJ_FUNC void lj_alloc_destroy(void *msp);
|
||||
LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
** Target architecture selection.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ARCH_H
|
||||
#define _LJ_ARCH_H
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
/* Target endianess. */
|
||||
#define LUAJIT_LE 0
|
||||
#define LUAJIT_BE 1
|
||||
|
||||
/* Target architectures. */
|
||||
#define LUAJIT_ARCH_X86 1
|
||||
#define LUAJIT_ARCH_x86 1
|
||||
#define LUAJIT_ARCH_X64 2
|
||||
#define LUAJIT_ARCH_x64 2
|
||||
#define LUAJIT_ARCH_ARM 3
|
||||
#define LUAJIT_ARCH_arm 3
|
||||
#define LUAJIT_ARCH_ARM64 4
|
||||
#define LUAJIT_ARCH_arm64 4
|
||||
#define LUAJIT_ARCH_PPC 5
|
||||
#define LUAJIT_ARCH_ppc 5
|
||||
#define LUAJIT_ARCH_MIPS 6
|
||||
#define LUAJIT_ARCH_mips 6
|
||||
#define LUAJIT_ARCH_MIPS32 6
|
||||
#define LUAJIT_ARCH_mips32 6
|
||||
#define LUAJIT_ARCH_MIPS64 7
|
||||
#define LUAJIT_ARCH_mips64 7
|
||||
|
||||
/* Target OS. */
|
||||
#define LUAJIT_OS_OTHER 0
|
||||
#define LUAJIT_OS_WINDOWS 1
|
||||
#define LUAJIT_OS_LINUX 2
|
||||
#define LUAJIT_OS_OSX 3
|
||||
#define LUAJIT_OS_BSD 4
|
||||
#define LUAJIT_OS_POSIX 5
|
||||
|
||||
/* Select native target if no target defined. */
|
||||
#ifndef LUAJIT_TARGET
|
||||
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_X86
|
||||
#elif defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_X64
|
||||
#elif defined(__arm__) || defined(__arm) || defined(__ARM__) || defined(__ARM)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_ARM
|
||||
#elif defined(__aarch64__)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_ARM64
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__PPC__) || defined(__PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__POWERPC) || defined(_M_PPC)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_PPC
|
||||
#elif defined(__mips64__) || defined(__mips64) || defined(__MIPS64__) || defined(__MIPS64)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_MIPS64
|
||||
#elif defined(__mips__) || defined(__mips) || defined(__MIPS__) || defined(__MIPS)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_MIPS32
|
||||
#else
|
||||
#error "No support for this architecture (yet)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Select native OS if no target OS defined. */
|
||||
#ifndef LUAJIT_OS
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX_VER)
|
||||
#define LUAJIT_OS LUAJIT_OS_WINDOWS
|
||||
#elif defined(__linux__)
|
||||
#define LUAJIT_OS LUAJIT_OS_LINUX
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#define LUAJIT_OS LUAJIT_OS_OSX
|
||||
#elif (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
|
||||
defined(__NetBSD__) || defined(__OpenBSD__) || \
|
||||
defined(__DragonFly__)) && !defined(__ORBIS__)
|
||||
#define LUAJIT_OS LUAJIT_OS_BSD
|
||||
#elif (defined(__sun__) && defined(__svr4__)) || defined(__HAIKU__)
|
||||
#define LUAJIT_OS LUAJIT_OS_POSIX
|
||||
#elif defined(__CYGWIN__)
|
||||
#define LJ_TARGET_CYGWIN 1
|
||||
#define LUAJIT_OS LUAJIT_OS_POSIX
|
||||
#else
|
||||
#define LUAJIT_OS LUAJIT_OS_OTHER
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Set target OS properties. */
|
||||
#if LUAJIT_OS == LUAJIT_OS_WINDOWS
|
||||
#define LJ_OS_NAME "Windows"
|
||||
#elif LUAJIT_OS == LUAJIT_OS_LINUX
|
||||
#define LJ_OS_NAME "Linux"
|
||||
#elif LUAJIT_OS == LUAJIT_OS_OSX
|
||||
#define LJ_OS_NAME "OSX"
|
||||
#elif LUAJIT_OS == LUAJIT_OS_BSD
|
||||
#define LJ_OS_NAME "BSD"
|
||||
#elif LUAJIT_OS == LUAJIT_OS_POSIX
|
||||
#define LJ_OS_NAME "POSIX"
|
||||
#else
|
||||
#define LJ_OS_NAME "Other"
|
||||
#endif
|
||||
|
||||
#define LJ_TARGET_WINDOWS (LUAJIT_OS == LUAJIT_OS_WINDOWS)
|
||||
#define LJ_TARGET_LINUX (LUAJIT_OS == LUAJIT_OS_LINUX)
|
||||
#define LJ_TARGET_OSX (LUAJIT_OS == LUAJIT_OS_OSX)
|
||||
#define LJ_TARGET_IOS (LJ_TARGET_OSX && (LUAJIT_TARGET == LUAJIT_ARCH_ARM || LUAJIT_TARGET == LUAJIT_ARCH_ARM64))
|
||||
#define LJ_TARGET_POSIX (LUAJIT_OS > LUAJIT_OS_WINDOWS)
|
||||
#define LJ_TARGET_DLOPEN LJ_TARGET_POSIX
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#define LJ_TARGET_PS3 1
|
||||
#define LJ_TARGET_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#ifdef __ORBIS__
|
||||
#define LJ_TARGET_PS4 1
|
||||
#define LJ_TARGET_CONSOLE 1
|
||||
#undef NULL
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
#ifdef __psp2__
|
||||
#define LJ_TARGET_PSVITA 1
|
||||
#define LJ_TARGET_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#if _XBOX_VER >= 200
|
||||
#define LJ_TARGET_XBOX360 1
|
||||
#define LJ_TARGET_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#ifdef _DURANGO
|
||||
#define LJ_TARGET_XBOXONE 1
|
||||
#define LJ_TARGET_CONSOLE 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#endif
|
||||
|
||||
#define LJ_NUMMODE_SINGLE 0 /* Single-number mode only. */
|
||||
#define LJ_NUMMODE_SINGLE_DUAL 1 /* Default to single-number mode. */
|
||||
#define LJ_NUMMODE_DUAL 2 /* Dual-number mode only. */
|
||||
#define LJ_NUMMODE_DUAL_SINGLE 3 /* Default to dual-number mode. */
|
||||
|
||||
/* Set target architecture properties. */
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_X86
|
||||
|
||||
#define LJ_ARCH_NAME "x86"
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
|
||||
#define LJ_ABI_WIN 1
|
||||
#else
|
||||
#define LJ_ABI_WIN 0
|
||||
#endif
|
||||
#define LJ_TARGET_X86 1
|
||||
#define LJ_TARGET_X86ORX64 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
#define LJ_TARGET_MASKSHIFT 1
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNALIGNED 1
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_X64
|
||||
|
||||
#define LJ_ARCH_NAME "x64"
|
||||
#define LJ_ARCH_BITS 64
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
|
||||
#define LJ_ABI_WIN 1
|
||||
#else
|
||||
#define LJ_ABI_WIN 0
|
||||
#endif
|
||||
#define LJ_TARGET_X64 1
|
||||
#define LJ_TARGET_X86ORX64 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
#define LJ_TARGET_JUMPRANGE 31 /* +-2^31 = +-2GB */
|
||||
#define LJ_TARGET_MASKSHIFT 1
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNALIGNED 1
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL
|
||||
#ifdef LUAJIT_ENABLE_GC64
|
||||
#define LJ_TARGET_GC64 1
|
||||
#endif
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM
|
||||
|
||||
#define LJ_ARCH_NAME "arm"
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#if !defined(LJ_ARCH_HASFPU) && __SOFTFP__
|
||||
#define LJ_ARCH_HASFPU 0
|
||||
#endif
|
||||
#if !defined(LJ_ABI_SOFTFP) && !__ARM_PCS_VFP
|
||||
#define LJ_ABI_SOFTFP 1
|
||||
#endif
|
||||
#define LJ_ABI_EABI 1
|
||||
#define LJ_TARGET_ARM 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
|
||||
#define LJ_TARGET_MASKSHIFT 0
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
|
||||
#if __ARM_ARCH____ARM_ARCH_8__ || __ARM_ARCH_8A__
|
||||
#define LJ_ARCH_VERSION 80
|
||||
#elif __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__ || __ARM_ARCH_7VE__
|
||||
#define LJ_ARCH_VERSION 70
|
||||
#elif __ARM_ARCH_6T2__
|
||||
#define LJ_ARCH_VERSION 61
|
||||
#elif __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6K__ || __ARM_ARCH_6Z__ || __ARM_ARCH_6ZK__
|
||||
#define LJ_ARCH_VERSION 60
|
||||
#else
|
||||
#define LJ_ARCH_VERSION 50
|
||||
#endif
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
|
||||
|
||||
#define LJ_ARCH_BITS 64
|
||||
#if defined(__AARCH64EB__)
|
||||
#define LJ_ARCH_NAME "arm64be"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#else
|
||||
#define LJ_ARCH_NAME "arm64"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#endif
|
||||
#define LJ_TARGET_ARM64 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
#define LJ_TARGET_JUMPRANGE 27 /* +-2^27 = +-128MB */
|
||||
#define LJ_TARGET_MASKSHIFT 1
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_TARGET_GC64 1
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
|
||||
#define LJ_ARCH_VERSION 80
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_PPC
|
||||
|
||||
#ifndef LJ_ARCH_ENDIAN
|
||||
#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#else
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _LP64
|
||||
#define LJ_ARCH_BITS 64
|
||||
#if LJ_ARCH_ENDIAN == LUAJIT_LE
|
||||
#define LJ_ARCH_NAME "ppc64le"
|
||||
#else
|
||||
#define LJ_ARCH_NAME "ppc64"
|
||||
#endif
|
||||
#else
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_NAME "ppc"
|
||||
#endif
|
||||
|
||||
#define LJ_TARGET_PPC 1
|
||||
#define LJ_TARGET_EHRETREG 3
|
||||
#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
|
||||
#define LJ_TARGET_MASKSHIFT 0
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||
|
||||
#if LJ_TARGET_CONSOLE
|
||||
#define LJ_ARCH_PPC32ON64 1
|
||||
#define LJ_ARCH_NOFFI 1
|
||||
#elif LJ_ARCH_BITS == 64
|
||||
#define LJ_ARCH_PPC64 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#endif
|
||||
|
||||
#if _ARCH_PWR7
|
||||
#define LJ_ARCH_VERSION 70
|
||||
#elif _ARCH_PWR6
|
||||
#define LJ_ARCH_VERSION 60
|
||||
#elif _ARCH_PWR5X
|
||||
#define LJ_ARCH_VERSION 51
|
||||
#elif _ARCH_PWR5
|
||||
#define LJ_ARCH_VERSION 50
|
||||
#elif _ARCH_PWR4
|
||||
#define LJ_ARCH_VERSION 40
|
||||
#else
|
||||
#define LJ_ARCH_VERSION 0
|
||||
#endif
|
||||
#if _ARCH_PPCSQ
|
||||
#define LJ_ARCH_SQRT 1
|
||||
#endif
|
||||
#if _ARCH_PWR5X
|
||||
#define LJ_ARCH_ROUND 1
|
||||
#endif
|
||||
#if __PPU__
|
||||
#define LJ_ARCH_CELL 1
|
||||
#endif
|
||||
#if LJ_TARGET_XBOX360
|
||||
#define LJ_ARCH_XENON 1
|
||||
#endif
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 || LUAJIT_TARGET == LUAJIT_ARCH_MIPS64
|
||||
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
|
||||
#define LJ_ARCH_NAME "mipsel"
|
||||
#else
|
||||
#define LJ_ARCH_NAME "mips64el"
|
||||
#endif
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#else
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
|
||||
#define LJ_ARCH_NAME "mips"
|
||||
#else
|
||||
#define LJ_ARCH_NAME "mips64"
|
||||
#endif
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#endif
|
||||
|
||||
#if !defined(LJ_ARCH_HASFPU)
|
||||
#ifdef __mips_soft_float
|
||||
#define LJ_ARCH_HASFPU 0
|
||||
#else
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LJ_ABI_SOFTFP)
|
||||
#ifdef __mips_soft_float
|
||||
#define LJ_ABI_SOFTFP 1
|
||||
#else
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_TARGET_MIPS32 1
|
||||
#else
|
||||
#if LJ_ABI_SOFTFP || !LJ_ARCH_HASFPU
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#endif
|
||||
#define LJ_ARCH_BITS 64
|
||||
#define LJ_TARGET_MIPS64 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#endif
|
||||
#define LJ_TARGET_MIPS 1
|
||||
#define LJ_TARGET_EHRETREG 4
|
||||
#define LJ_TARGET_JUMPRANGE 27 /* 2*2^27 = 256MB-aligned region */
|
||||
#define LJ_TARGET_MASKSHIFT 1
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
|
||||
#if _MIPS_ARCH_MIPS32R2 || _MIPS_ARCH_MIPS64R2
|
||||
#define LJ_ARCH_VERSION 20
|
||||
#else
|
||||
#define LJ_ARCH_VERSION 10
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "No target architecture defined"
|
||||
#endif
|
||||
|
||||
#ifndef LJ_PAGESIZE
|
||||
#define LJ_PAGESIZE 4096
|
||||
#endif
|
||||
|
||||
/* Check for minimum required compiler versions. */
|
||||
#if defined(__GNUC__)
|
||||
#if LJ_TARGET_X86
|
||||
#if (__GNUC__ < 3) || ((__GNUC__ == 3) && __GNUC_MINOR__ < 4)
|
||||
#error "Need at least GCC 3.4 or newer"
|
||||
#endif
|
||||
#elif LJ_TARGET_X64
|
||||
#if __GNUC__ < 4
|
||||
#error "Need at least GCC 4.0 or newer"
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM
|
||||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2)
|
||||
#error "Need at least GCC 4.2 or newer"
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM64
|
||||
#if __clang__
|
||||
#if ((__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5)) && !defined(__NX_TOOLCHAIN_MAJOR__)
|
||||
#error "Need at least Clang 3.5 or newer"
|
||||
#endif
|
||||
#else
|
||||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 8)
|
||||
#error "Need at least GCC 4.8 or newer"
|
||||
#endif
|
||||
#endif
|
||||
#elif !LJ_TARGET_PS3
|
||||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 3)
|
||||
#error "Need at least GCC 4.3 or newer"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Check target-specific constraints. */
|
||||
#ifndef _BUILDVM_H
|
||||
#if LJ_TARGET_X64
|
||||
#if __USING_SJLJ_EXCEPTIONS__
|
||||
#error "Need a C compiler with native exception handling on x64"
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM
|
||||
#if defined(__ARMEB__)
|
||||
#error "No support for big-endian ARM"
|
||||
#endif
|
||||
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__
|
||||
#error "No support for Cortex-M CPUs"
|
||||
#endif
|
||||
#if !(__ARM_EABI__ || LJ_TARGET_IOS)
|
||||
#error "Only ARM EABI or iOS 3.0+ ABI is supported"
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM64
|
||||
#if defined(_ILP32)
|
||||
#error "No support for ILP32 model on ARM64"
|
||||
#endif
|
||||
#elif LJ_TARGET_PPC
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#error "No support for PowerPC CPUs without double-precision FPU"
|
||||
#endif
|
||||
#if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE
|
||||
#error "No support for little-endian PPC32"
|
||||
#endif
|
||||
#if LJ_ARCH_PPC64
|
||||
#error "No support for PowerPC 64 bit mode (yet)"
|
||||
#endif
|
||||
#ifdef __NO_FPRS__
|
||||
#error "No support for PPC/e500 anymore (use LuaJIT 2.0)"
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS32
|
||||
#if !((defined(_MIPS_SIM_ABI32) && _MIPS_SIM == _MIPS_SIM_ABI32) || (defined(_ABIO32) && _MIPS_SIM == _ABIO32))
|
||||
#error "Only o32 ABI supported for MIPS32"
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS64
|
||||
#if !((defined(_MIPS_SIM_ABI64) && _MIPS_SIM == _MIPS_SIM_ABI64) || (defined(_ABI64) && _MIPS_SIM == _ABI64))
|
||||
#error "Only n64 ABI supported for MIPS64"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Enable or disable the dual-number mode for the VM. */
|
||||
#if (LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE && LUAJIT_NUMMODE == 2) || \
|
||||
(LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL && LUAJIT_NUMMODE == 1)
|
||||
#error "No support for this number mode on this architecture"
|
||||
#endif
|
||||
#if LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL || \
|
||||
(LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL_SINGLE && LUAJIT_NUMMODE != 1) || \
|
||||
(LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE_DUAL && LUAJIT_NUMMODE == 2)
|
||||
#define LJ_DUALNUM 1
|
||||
#else
|
||||
#define LJ_DUALNUM 0
|
||||
#endif
|
||||
|
||||
#if LJ_TARGET_IOS || LJ_TARGET_CONSOLE
|
||||
/* Runtime code generation is restricted on iOS. Complain to Apple, not me. */
|
||||
/* Ditto for the consoles. Complain to Sony or MS, not me. */
|
||||
#ifndef LUAJIT_ENABLE_JIT
|
||||
#define LJ_OS_NOJIT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 64 bit GC references. */
|
||||
#if LJ_TARGET_GC64
|
||||
#define LJ_GC64 1
|
||||
#else
|
||||
#define LJ_GC64 1
|
||||
#endif
|
||||
|
||||
/* 2-slot frame info. */
|
||||
#if LJ_GC64
|
||||
#define LJ_FR2 1
|
||||
#else
|
||||
#define LJ_FR2 0
|
||||
#endif
|
||||
|
||||
/* Disable or enable the JIT compiler. */
|
||||
#if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT)
|
||||
#define LJ_HASJIT 0
|
||||
#else
|
||||
#define LJ_HASJIT 1
|
||||
#endif
|
||||
|
||||
/* Disable or enable the FFI extension. */
|
||||
#if defined(LUAJIT_DISABLE_FFI) || defined(LJ_ARCH_NOFFI)
|
||||
#define LJ_HASFFI 0
|
||||
#else
|
||||
#define LJ_HASFFI 1
|
||||
#endif
|
||||
|
||||
#if defined(LUAJIT_DISABLE_PROFILE)
|
||||
#define LJ_HASPROFILE 0
|
||||
#elif LJ_TARGET_POSIX
|
||||
#define LJ_HASPROFILE 1
|
||||
#define LJ_PROFILE_SIGPROF 1
|
||||
#elif LJ_TARGET_PS3
|
||||
#define LJ_HASPROFILE 1
|
||||
#define LJ_PROFILE_PTHREAD 1
|
||||
#elif LJ_TARGET_WINDOWS || LJ_TARGET_XBOX360
|
||||
#define LJ_HASPROFILE 1
|
||||
#define LJ_PROFILE_WTHREAD 1
|
||||
#else
|
||||
#define LJ_HASPROFILE 0
|
||||
#endif
|
||||
|
||||
#ifndef LJ_ARCH_HASFPU
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#endif
|
||||
#ifndef LJ_ABI_SOFTFP
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#define LJ_SOFTFP (!LJ_ARCH_HASFPU)
|
||||
|
||||
#if LJ_ARCH_ENDIAN == LUAJIT_BE
|
||||
#define LJ_LE 0
|
||||
#define LJ_BE 1
|
||||
#define LJ_ENDIAN_SELECT(le, be) be
|
||||
#define LJ_ENDIAN_LOHI(lo, hi) hi lo
|
||||
#else
|
||||
#define LJ_LE 1
|
||||
#define LJ_BE 0
|
||||
#define LJ_ENDIAN_SELECT(le, be) le
|
||||
#define LJ_ENDIAN_LOHI(lo, hi) lo hi
|
||||
#endif
|
||||
|
||||
#if LJ_ARCH_BITS == 32
|
||||
#define LJ_32 1
|
||||
#define LJ_64 0
|
||||
#else
|
||||
#define LJ_32 0
|
||||
#define LJ_64 1
|
||||
#endif
|
||||
|
||||
#ifndef LJ_TARGET_UNALIGNED
|
||||
#define LJ_TARGET_UNALIGNED 0
|
||||
#endif
|
||||
|
||||
/* Various workarounds for embedded operating systems or weak C runtimes. */
|
||||
#if defined(__ANDROID__) || defined(__symbian__) || LJ_TARGET_XBOX360 || LJ_TARGET_WINDOWS
|
||||
#define LUAJIT_NO_LOG2
|
||||
#endif
|
||||
#if defined(__symbian__) || LJ_TARGET_WINDOWS
|
||||
#define LUAJIT_NO_EXP2
|
||||
#endif
|
||||
#if LJ_TARGET_CONSOLE || (LJ_TARGET_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)
|
||||
#define LJ_NO_SYSTEM 1
|
||||
#endif
|
||||
|
||||
#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__
|
||||
/* NYI: no support for compact unwind specification, yet. */
|
||||
#define LUAJIT_NO_UNWIND 1
|
||||
#endif
|
||||
|
||||
#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4
|
||||
#define LJ_NO_UNWIND 1
|
||||
#endif
|
||||
|
||||
/* Compatibility with Lua 5.1 vs. 5.2. */
|
||||
#ifdef LUAJIT_ENABLE_LUA52COMPAT
|
||||
#define LJ_52 1
|
||||
#else
|
||||
#define LJ_52 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
** IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ASM_H
|
||||
#define _LJ_ASM_H
|
||||
|
||||
#include "lj_jit.h"
|
||||
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC void lj_asm_trace(jit_State *J, GCtrace *T);
|
||||
LJ_FUNC void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno,
|
||||
MCode *target);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,265 +0,0 @@
|
||||
/*
|
||||
** Bytecode instruction format.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_BC_H
|
||||
#define _LJ_BC_H
|
||||
|
||||
#include "lj_def.h"
|
||||
#include "lj_arch.h"
|
||||
|
||||
/* Bytecode instruction format, 32 bit wide, fields of 8 or 16 bit:
|
||||
**
|
||||
** +----+----+----+----+
|
||||
** | B | C | A | OP | Format ABC
|
||||
** +----+----+----+----+
|
||||
** | D | A | OP | Format AD
|
||||
** +--------------------
|
||||
** MSB LSB
|
||||
**
|
||||
** In-memory instructions are always stored in host byte order.
|
||||
*/
|
||||
|
||||
/* Operand ranges and related constants. */
|
||||
#define BCMAX_A 0xff
|
||||
#define BCMAX_B 0xff
|
||||
#define BCMAX_C 0xff
|
||||
#define BCMAX_D 0xffff
|
||||
#define BCBIAS_J 0x8000
|
||||
#define NO_REG BCMAX_A
|
||||
#define NO_JMP (~(BCPos)0)
|
||||
|
||||
/* Macros to get instruction fields. */
|
||||
#define bc_op(i) ((BCOp)((i)&0xff))
|
||||
#define bc_a(i) ((BCReg)(((i)>>8)&0xff))
|
||||
#define bc_b(i) ((BCReg)((i)>>24))
|
||||
#define bc_c(i) ((BCReg)(((i)>>16)&0xff))
|
||||
#define bc_d(i) ((BCReg)((i)>>16))
|
||||
#define bc_j(i) ((ptrdiff_t)bc_d(i)-BCBIAS_J)
|
||||
|
||||
/* Macros to set instruction fields. */
|
||||
#define setbc_byte(p, x, ofs) \
|
||||
((uint8_t *)(p))[LJ_ENDIAN_SELECT(ofs, 3-ofs)] = (uint8_t)(x)
|
||||
#define setbc_op(p, x) setbc_byte(p, (x), 0)
|
||||
#define setbc_a(p, x) setbc_byte(p, (x), 1)
|
||||
#define setbc_b(p, x) setbc_byte(p, (x), 3)
|
||||
#define setbc_c(p, x) setbc_byte(p, (x), 2)
|
||||
#define setbc_d(p, x) \
|
||||
((uint16_t *)(p))[LJ_ENDIAN_SELECT(1, 0)] = (uint16_t)(x)
|
||||
#define setbc_j(p, x) setbc_d(p, (BCPos)((int32_t)(x)+BCBIAS_J))
|
||||
|
||||
/* Macros to compose instructions. */
|
||||
#define BCINS_ABC(o, a, b, c) \
|
||||
(((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(b)<<24)|((BCIns)(c)<<16))
|
||||
#define BCINS_AD(o, a, d) \
|
||||
(((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(d)<<16))
|
||||
#define BCINS_AJ(o, a, j) BCINS_AD(o, a, (BCPos)((int32_t)(j)+BCBIAS_J))
|
||||
|
||||
/* Bytecode instruction definition. Order matters, see below.
|
||||
**
|
||||
** (name, filler, Amode, Bmode, Cmode or Dmode, metamethod)
|
||||
**
|
||||
** The opcode name suffixes specify the type for RB/RC or RD:
|
||||
** V = variable slot
|
||||
** S = string const
|
||||
** N = number const
|
||||
** P = primitive type (~itype)
|
||||
** B = unsigned byte literal
|
||||
** M = multiple args/results
|
||||
*/
|
||||
#define BCDEF(_) \
|
||||
/* Comparison ops. ORDER OPR. */ \
|
||||
_(ISLT, var, ___, var, lt) \
|
||||
_(ISGE, var, ___, var, lt) \
|
||||
_(ISLE, var, ___, var, le) \
|
||||
_(ISGT, var, ___, var, le) \
|
||||
\
|
||||
_(ISEQV, var, ___, var, eq) \
|
||||
_(ISNEV, var, ___, var, eq) \
|
||||
_(ISEQS, var, ___, str, eq) \
|
||||
_(ISNES, var, ___, str, eq) \
|
||||
_(ISEQN, var, ___, num, eq) \
|
||||
_(ISNEN, var, ___, num, eq) \
|
||||
_(ISEQP, var, ___, pri, eq) \
|
||||
_(ISNEP, var, ___, pri, eq) \
|
||||
\
|
||||
/* Unary test and copy ops. */ \
|
||||
_(ISTC, dst, ___, var, ___) \
|
||||
_(ISFC, dst, ___, var, ___) \
|
||||
_(IST, ___, ___, var, ___) \
|
||||
_(ISF, ___, ___, var, ___) \
|
||||
_(ISTYPE, var, ___, lit, ___) \
|
||||
_(ISNUM, var, ___, lit, ___) \
|
||||
\
|
||||
/* Unary ops. */ \
|
||||
_(MOV, dst, ___, var, ___) \
|
||||
_(NOT, dst, ___, var, ___) \
|
||||
_(UNM, dst, ___, var, unm) \
|
||||
_(LEN, dst, ___, var, len) \
|
||||
\
|
||||
/* Binary ops. ORDER OPR. VV last, POW must be next. */ \
|
||||
_(ADDVN, dst, var, num, add) \
|
||||
_(SUBVN, dst, var, num, sub) \
|
||||
_(MULVN, dst, var, num, mul) \
|
||||
_(DIVVN, dst, var, num, div) \
|
||||
_(MODVN, dst, var, num, mod) \
|
||||
\
|
||||
_(ADDNV, dst, var, num, add) \
|
||||
_(SUBNV, dst, var, num, sub) \
|
||||
_(MULNV, dst, var, num, mul) \
|
||||
_(DIVNV, dst, var, num, div) \
|
||||
_(MODNV, dst, var, num, mod) \
|
||||
\
|
||||
_(ADDVV, dst, var, var, add) \
|
||||
_(SUBVV, dst, var, var, sub) \
|
||||
_(MULVV, dst, var, var, mul) \
|
||||
_(DIVVV, dst, var, var, div) \
|
||||
_(MODVV, dst, var, var, mod) \
|
||||
\
|
||||
_(POW, dst, var, var, pow) \
|
||||
_(CAT, dst, rbase, rbase, concat) \
|
||||
\
|
||||
/* Constant ops. */ \
|
||||
_(KSTR, dst, ___, str, ___) \
|
||||
_(KCDATA, dst, ___, cdata, ___) \
|
||||
_(KSHORT, dst, ___, lits, ___) \
|
||||
_(KNUM, dst, ___, num, ___) \
|
||||
_(KPRI, dst, ___, pri, ___) \
|
||||
_(KNIL, base, ___, base, ___) \
|
||||
\
|
||||
/* Upvalue and function ops. */ \
|
||||
_(UGET, dst, ___, uv, ___) \
|
||||
_(USETV, uv, ___, var, ___) \
|
||||
_(USETS, uv, ___, str, ___) \
|
||||
_(USETN, uv, ___, num, ___) \
|
||||
_(USETP, uv, ___, pri, ___) \
|
||||
_(UCLO, rbase, ___, jump, ___) \
|
||||
_(FNEW, dst, ___, func, gc) \
|
||||
\
|
||||
/* Table ops. */ \
|
||||
_(TNEW, dst, ___, lit, gc) \
|
||||
_(TDUP, dst, ___, tab, gc) \
|
||||
_(GGET, dst, ___, str, index) \
|
||||
_(GSET, var, ___, str, newindex) \
|
||||
_(TGETV, dst, var, var, index) \
|
||||
_(TGETS, dst, var, str, index) \
|
||||
_(TGETB, dst, var, lit, index) \
|
||||
_(TGETR, dst, var, var, index) \
|
||||
_(TSETV, var, var, var, newindex) \
|
||||
_(TSETS, var, var, str, newindex) \
|
||||
_(TSETB, var, var, lit, newindex) \
|
||||
_(TSETM, base, ___, num, newindex) \
|
||||
_(TSETR, var, var, var, newindex) \
|
||||
\
|
||||
/* Calls and vararg handling. T = tail call. */ \
|
||||
_(CALLM, base, lit, lit, call) \
|
||||
_(CALL, base, lit, lit, call) \
|
||||
_(CALLMT, base, ___, lit, call) \
|
||||
_(CALLT, base, ___, lit, call) \
|
||||
_(ITERC, base, lit, lit, call) \
|
||||
_(ITERN, base, lit, lit, call) \
|
||||
_(VARG, base, lit, lit, ___) \
|
||||
_(ISNEXT, base, ___, jump, ___) \
|
||||
\
|
||||
/* Returns. */ \
|
||||
_(RETM, base, ___, lit, ___) \
|
||||
_(RET, rbase, ___, lit, ___) \
|
||||
_(RET0, rbase, ___, lit, ___) \
|
||||
_(RET1, rbase, ___, lit, ___) \
|
||||
\
|
||||
/* Loops and branches. I/J = interp/JIT, I/C/L = init/call/loop. */ \
|
||||
_(FORI, base, ___, jump, ___) \
|
||||
_(JFORI, base, ___, jump, ___) \
|
||||
\
|
||||
_(FORL, base, ___, jump, ___) \
|
||||
_(IFORL, base, ___, jump, ___) \
|
||||
_(JFORL, base, ___, lit, ___) \
|
||||
\
|
||||
_(ITERL, base, ___, jump, ___) \
|
||||
_(IITERL, base, ___, jump, ___) \
|
||||
_(JITERL, base, ___, lit, ___) \
|
||||
\
|
||||
_(LOOP, rbase, ___, jump, ___) \
|
||||
_(ILOOP, rbase, ___, jump, ___) \
|
||||
_(JLOOP, rbase, ___, lit, ___) \
|
||||
\
|
||||
_(JMP, rbase, ___, jump, ___) \
|
||||
\
|
||||
/* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
|
||||
_(FUNCF, rbase, ___, ___, ___) \
|
||||
_(IFUNCF, rbase, ___, ___, ___) \
|
||||
_(JFUNCF, rbase, ___, lit, ___) \
|
||||
_(FUNCV, rbase, ___, ___, ___) \
|
||||
_(IFUNCV, rbase, ___, ___, ___) \
|
||||
_(JFUNCV, rbase, ___, lit, ___) \
|
||||
_(FUNCC, rbase, ___, ___, ___) \
|
||||
_(FUNCCW, rbase, ___, ___, ___)
|
||||
|
||||
/* Bytecode opcode numbers. */
|
||||
typedef enum {
|
||||
#define BCENUM(name, ma, mb, mc, mt) BC_##name,
|
||||
BCDEF(BCENUM)
|
||||
#undef BCENUM
|
||||
BC__MAX
|
||||
} BCOp;
|
||||
|
||||
LJ_STATIC_ASSERT((int)BC_ISEQV+1 == (int)BC_ISNEV);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISEQV^1) == (int)BC_ISNEV);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISEQS^1) == (int)BC_ISNES);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISEQN^1) == (int)BC_ISNEN);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISEQP^1) == (int)BC_ISNEP);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISLT^1) == (int)BC_ISGE);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISLE^1) == (int)BC_ISGT);
|
||||
LJ_STATIC_ASSERT(((int)BC_ISLT^3) == (int)BC_ISGT);
|
||||
LJ_STATIC_ASSERT((int)BC_IST-(int)BC_ISTC == (int)BC_ISF-(int)BC_ISFC);
|
||||
LJ_STATIC_ASSERT((int)BC_CALLT-(int)BC_CALL == (int)BC_CALLMT-(int)BC_CALLM);
|
||||
LJ_STATIC_ASSERT((int)BC_CALLMT + 1 == (int)BC_CALLT);
|
||||
LJ_STATIC_ASSERT((int)BC_RETM + 1 == (int)BC_RET);
|
||||
LJ_STATIC_ASSERT((int)BC_FORL + 1 == (int)BC_IFORL);
|
||||
LJ_STATIC_ASSERT((int)BC_FORL + 2 == (int)BC_JFORL);
|
||||
LJ_STATIC_ASSERT((int)BC_ITERL + 1 == (int)BC_IITERL);
|
||||
LJ_STATIC_ASSERT((int)BC_ITERL + 2 == (int)BC_JITERL);
|
||||
LJ_STATIC_ASSERT((int)BC_LOOP + 1 == (int)BC_ILOOP);
|
||||
LJ_STATIC_ASSERT((int)BC_LOOP + 2 == (int)BC_JLOOP);
|
||||
LJ_STATIC_ASSERT((int)BC_FUNCF + 1 == (int)BC_IFUNCF);
|
||||
LJ_STATIC_ASSERT((int)BC_FUNCF + 2 == (int)BC_JFUNCF);
|
||||
LJ_STATIC_ASSERT((int)BC_FUNCV + 1 == (int)BC_IFUNCV);
|
||||
LJ_STATIC_ASSERT((int)BC_FUNCV + 2 == (int)BC_JFUNCV);
|
||||
|
||||
/* This solves a circular dependency problem, change as needed. */
|
||||
#define FF_next_N 4
|
||||
|
||||
/* Stack slots used by FORI/FORL, relative to operand A. */
|
||||
enum {
|
||||
FORL_IDX, FORL_STOP, FORL_STEP, FORL_EXT
|
||||
};
|
||||
|
||||
/* Bytecode operand modes. ORDER BCMode */
|
||||
typedef enum {
|
||||
BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv, /* Mode A must be <= 7 */
|
||||
BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump, BCMcdata,
|
||||
BCM_max
|
||||
} BCMode;
|
||||
#define BCM___ BCMnone
|
||||
|
||||
#define bcmode_a(op) ((BCMode)(lj_bc_mode[op] & 7))
|
||||
#define bcmode_b(op) ((BCMode)((lj_bc_mode[op]>>3) & 15))
|
||||
#define bcmode_c(op) ((BCMode)((lj_bc_mode[op]>>7) & 15))
|
||||
#define bcmode_d(op) bcmode_c(op)
|
||||
#define bcmode_hasd(op) ((lj_bc_mode[op] & (15<<3)) == (BCMnone<<3))
|
||||
#define bcmode_mm(op) ((MMS)(lj_bc_mode[op]>>11))
|
||||
|
||||
#define BCMODE(name, ma, mb, mc, mm) \
|
||||
(BCM##ma|(BCM##mb<<3)|(BCM##mc<<7)|(MM_##mm<<11)),
|
||||
#define BCMODE_FF 0
|
||||
|
||||
static LJ_AINLINE int bc_isret(BCOp op)
|
||||
{
|
||||
return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
|
||||
}
|
||||
|
||||
LJ_DATA const uint16_t lj_bc_mode[];
|
||||
LJ_DATA const uint16_t lj_bc_ofs[];
|
||||
|
||||
#endif
|
||||
@@ -1,220 +0,0 @@
|
||||
/* This is a generated file. DO NOT EDIT! */
|
||||
|
||||
LJ_DATADEF const uint16_t lj_bc_ofs[] = {
|
||||
0,
|
||||
71,
|
||||
142,
|
||||
213,
|
||||
284,
|
||||
422,
|
||||
563,
|
||||
624,
|
||||
685,
|
||||
752,
|
||||
819,
|
||||
871,
|
||||
922,
|
||||
972,
|
||||
1022,
|
||||
1062,
|
||||
1102,
|
||||
1129,
|
||||
1160,
|
||||
1185,
|
||||
1216,
|
||||
1275,
|
||||
1348,
|
||||
1400,
|
||||
1452,
|
||||
1504,
|
||||
1556,
|
||||
1613,
|
||||
1665,
|
||||
1717,
|
||||
1769,
|
||||
1821,
|
||||
1856,
|
||||
1922,
|
||||
1988,
|
||||
2054,
|
||||
2120,
|
||||
2169,
|
||||
2248,
|
||||
2325,
|
||||
2359,
|
||||
2393,
|
||||
2422,
|
||||
2449,
|
||||
2473,
|
||||
2515,
|
||||
2550,
|
||||
2633,
|
||||
2712,
|
||||
2748,
|
||||
2781,
|
||||
2831,
|
||||
2894,
|
||||
3002,
|
||||
3091,
|
||||
3108,
|
||||
3125,
|
||||
3272,
|
||||
3394,
|
||||
3492,
|
||||
3545,
|
||||
3715,
|
||||
3944,
|
||||
4065,
|
||||
4199,
|
||||
4283,
|
||||
4328,
|
||||
4369,
|
||||
4373,
|
||||
4514,
|
||||
4581,
|
||||
4733,
|
||||
4913,
|
||||
5000,
|
||||
5004,
|
||||
5129,
|
||||
5217,
|
||||
5318,
|
||||
5414,
|
||||
5518,
|
||||
5537,
|
||||
5606,
|
||||
5672,
|
||||
5691,
|
||||
5734,
|
||||
5772,
|
||||
5791,
|
||||
5808,
|
||||
5929,
|
||||
5953,
|
||||
5972,
|
||||
6033,
|
||||
6086,
|
||||
6086,
|
||||
6203,
|
||||
6204,
|
||||
6286,
|
||||
8042,
|
||||
8109,
|
||||
8612,
|
||||
8716,
|
||||
8773,
|
||||
8904,
|
||||
8175,
|
||||
8335,
|
||||
8425,
|
||||
8478,
|
||||
8509,
|
||||
8962,
|
||||
9002,
|
||||
9622,
|
||||
9057,
|
||||
9366,
|
||||
9674,
|
||||
9800,
|
||||
9824,
|
||||
9851,
|
||||
9922,
|
||||
9962,
|
||||
10002,
|
||||
10042,
|
||||
10082,
|
||||
10122,
|
||||
10162,
|
||||
10202,
|
||||
10242,
|
||||
10282,
|
||||
10322,
|
||||
10585,
|
||||
10733,
|
||||
9882,
|
||||
10420,
|
||||
10362,
|
||||
10478,
|
||||
10536,
|
||||
10832,
|
||||
10891,
|
||||
11531,
|
||||
11929,
|
||||
11876,
|
||||
11998,
|
||||
12077,
|
||||
12159,
|
||||
12241,
|
||||
12323,
|
||||
11585,
|
||||
11682,
|
||||
11779,
|
||||
10950,
|
||||
10997,
|
||||
11118,
|
||||
11285,
|
||||
11367,
|
||||
11449
|
||||
};
|
||||
|
||||
LJ_DATADEF const uint16_t lj_bc_mode[] = {
|
||||
BCDEF(BCMODE)
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF,
|
||||
BCMODE_FF
|
||||
};
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
** Bytecode dump definitions.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_BCDUMP_H
|
||||
#define _LJ_BCDUMP_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_lex.h"
|
||||
|
||||
/* -- Bytecode dump format ------------------------------------------------ */
|
||||
|
||||
/*
|
||||
** dump = header proto+ 0U
|
||||
** header = ESC 'L' 'J' versionB flagsU [namelenU nameB*]
|
||||
** proto = lengthU pdata
|
||||
** pdata = phead bcinsW* uvdataH* kgc* knum* [debugB*]
|
||||
** phead = flagsB numparamsB framesizeB numuvB numkgcU numknU numbcU
|
||||
** [debuglenU [firstlineU numlineU]]
|
||||
** kgc = kgctypeU { ktab | (loU hiU) | (rloU rhiU iloU ihiU) | strB* }
|
||||
** knum = intU0 | (loU1 hiU)
|
||||
** ktab = narrayU nhashU karray* khash*
|
||||
** karray = ktabk
|
||||
** khash = ktabk ktabk
|
||||
** ktabk = ktabtypeU { intU | (loU hiU) | strB* }
|
||||
**
|
||||
** B = 8 bit, H = 16 bit, W = 32 bit, U = ULEB128 of W, U0/U1 = ULEB128 of W+1
|
||||
*/
|
||||
|
||||
/* Bytecode dump header. */
|
||||
#define BCDUMP_HEAD1 0x1b
|
||||
#define BCDUMP_HEAD2 0x4c
|
||||
#define BCDUMP_HEAD3 0x4a
|
||||
|
||||
/* If you perform *any* kind of private modifications to the bytecode itself
|
||||
** or to the dump format, you *must* set BCDUMP_VERSION to 0x80 or higher.
|
||||
*/
|
||||
#define BCDUMP_VERSION 2
|
||||
|
||||
/* Compatibility flags. */
|
||||
#define BCDUMP_F_BE 0x01
|
||||
#define BCDUMP_F_STRIP 0x02
|
||||
#define BCDUMP_F_FFI 0x04
|
||||
#define BCDUMP_F_FR2 0x08
|
||||
|
||||
#define BCDUMP_F_KNOWN (BCDUMP_F_FR2*2-1)
|
||||
|
||||
/* Type codes for the GC constants of a prototype. Plus length for strings. */
|
||||
enum {
|
||||
BCDUMP_KGC_CHILD, BCDUMP_KGC_TAB, BCDUMP_KGC_I64, BCDUMP_KGC_U64,
|
||||
BCDUMP_KGC_COMPLEX, BCDUMP_KGC_STR
|
||||
};
|
||||
|
||||
/* Type codes for the keys/values of a constant table. */
|
||||
enum {
|
||||
BCDUMP_KTAB_NIL, BCDUMP_KTAB_FALSE, BCDUMP_KTAB_TRUE,
|
||||
BCDUMP_KTAB_INT, BCDUMP_KTAB_NUM, BCDUMP_KTAB_STR
|
||||
};
|
||||
|
||||
/* -- Bytecode reader/writer ---------------------------------------------- */
|
||||
|
||||
LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer,
|
||||
void *data, int strip);
|
||||
LJ_FUNC GCproto *lj_bcread_proto(LexState *ls);
|
||||
LJ_FUNC GCproto *lj_bcread(LexState *ls);
|
||||
|
||||
#endif
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
** Buffer handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_BUF_H
|
||||
#define _LJ_BUF_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_str.h"
|
||||
|
||||
/* Resizable string buffers. Struct definition in lj_obj.h. */
|
||||
#define sbufB(sb) (mref((sb)->b, char))
|
||||
#define sbufP(sb) (mref((sb)->p, char))
|
||||
#define sbufE(sb) (mref((sb)->e, char))
|
||||
#define sbufL(sb) (mref((sb)->L, lua_State))
|
||||
#define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb))))
|
||||
#define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb))))
|
||||
#define sbufleft(sb) ((MSize)(sbufE((sb)) - sbufP((sb))))
|
||||
#define setsbufP(sb, q) (setmref((sb)->p, (q)))
|
||||
#define setsbufL(sb, l) (setmref((sb)->L, (l)))
|
||||
|
||||
/* Buffer management */
|
||||
LJ_FUNC char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz);
|
||||
LJ_FUNC char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz);
|
||||
LJ_FUNC void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb);
|
||||
LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
|
||||
|
||||
static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
|
||||
{
|
||||
setsbufL(sb, L);
|
||||
setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL);
|
||||
}
|
||||
|
||||
static LJ_AINLINE void lj_buf_reset(SBuf *sb)
|
||||
{
|
||||
setmrefr(sb->p, sb->b);
|
||||
}
|
||||
|
||||
static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
|
||||
{
|
||||
SBuf *sb = &G(L)->tmpbuf;
|
||||
setsbufL(sb, L);
|
||||
lj_buf_reset(sb);
|
||||
return sb;
|
||||
}
|
||||
|
||||
static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
|
||||
{
|
||||
lj_mem_free(g, sbufB(sb), sbufsz(sb));
|
||||
}
|
||||
|
||||
static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
|
||||
{
|
||||
if (LJ_UNLIKELY(sz > sbufsz(sb)))
|
||||
return lj_buf_need2(sb, sz);
|
||||
return sbufB(sb);
|
||||
}
|
||||
|
||||
static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
|
||||
{
|
||||
if (LJ_UNLIKELY(sz > sbufleft(sb)))
|
||||
return lj_buf_more2(sb, sz);
|
||||
return sbufP(sb);
|
||||
}
|
||||
|
||||
/* Low-level buffer put operations */
|
||||
LJ_FUNC SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len);
|
||||
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
|
||||
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
|
||||
|
||||
static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
|
||||
{
|
||||
return (char *)memcpy(p, q, len) + len;
|
||||
}
|
||||
|
||||
static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
|
||||
{
|
||||
char *p = lj_buf_more(sb, 1);
|
||||
*p++ = (char)c;
|
||||
setsbufP(sb, p);
|
||||
}
|
||||
|
||||
/* High-level buffer put operations */
|
||||
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s);
|
||||
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s);
|
||||
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s);
|
||||
LJ_FUNC SBuf *lj_buf_putstr_rep(SBuf *sb, GCstr *s, int32_t rep);
|
||||
LJ_FUNC SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep,
|
||||
int32_t i, int32_t e);
|
||||
|
||||
/* Miscellaneous buffer operations */
|
||||
LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
|
||||
LJ_FUNC GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2);
|
||||
LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
|
||||
|
||||
static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
|
||||
{
|
||||
return lj_str_new(L, sbufB(sb), sbuflen(sb));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
** C data arithmetic.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CARITH_H
|
||||
#define _LJ_CARITH_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
|
||||
|
||||
#if LJ_32
|
||||
LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);
|
||||
LJ_FUNC uint64_t lj_carith_shr64(uint64_t x, int32_t sh);
|
||||
LJ_FUNC uint64_t lj_carith_sar64(uint64_t x, int32_t sh);
|
||||
LJ_FUNC uint64_t lj_carith_rol64(uint64_t x, int32_t sh);
|
||||
LJ_FUNC uint64_t lj_carith_ror64(uint64_t x, int32_t sh);
|
||||
#endif
|
||||
LJ_FUNC uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op);
|
||||
LJ_FUNC uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id);
|
||||
|
||||
#if LJ_32 && LJ_HASJIT
|
||||
LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
|
||||
#endif
|
||||
LJ_FUNC uint64_t lj_carith_divu64(uint64_t a, uint64_t b);
|
||||
LJ_FUNC int64_t lj_carith_divi64(int64_t a, int64_t b);
|
||||
LJ_FUNC uint64_t lj_carith_modu64(uint64_t a, uint64_t b);
|
||||
LJ_FUNC int64_t lj_carith_modi64(int64_t a, int64_t b);
|
||||
LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k);
|
||||
LJ_FUNC int64_t lj_carith_powi64(int64_t x, int64_t k);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
** FFI C call handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CCALL_H
|
||||
#define _LJ_CCALL_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_ctype.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* -- C calling conventions ----------------------------------------------- */
|
||||
|
||||
#if LJ_TARGET_X86ORX64
|
||||
|
||||
#if LJ_TARGET_X86
|
||||
#define CCALL_NARG_GPR 2 /* For fastcall arguments. */
|
||||
#define CCALL_NARG_FPR 0
|
||||
#define CCALL_NRET_GPR 2
|
||||
#define CCALL_NRET_FPR 1 /* For FP results on x87 stack. */
|
||||
#define CCALL_ALIGN_STACKARG 0 /* Don't align argument on stack. */
|
||||
#elif LJ_ABI_WIN
|
||||
#define CCALL_NARG_GPR 4
|
||||
#define CCALL_NARG_FPR 4
|
||||
#define CCALL_NRET_GPR 1
|
||||
#define CCALL_NRET_FPR 1
|
||||
#define CCALL_SPS_EXTRA 4
|
||||
#else
|
||||
#define CCALL_NARG_GPR 6
|
||||
#define CCALL_NARG_FPR 8
|
||||
#define CCALL_NRET_GPR 2
|
||||
#define CCALL_NRET_FPR 2
|
||||
#define CCALL_VECTOR_REG 1 /* Pass vectors in registers. */
|
||||
#endif
|
||||
|
||||
#define CCALL_SPS_FREE 1
|
||||
#define CCALL_ALIGN_CALLSTATE 16
|
||||
|
||||
typedef LJ_ALIGN(16) union FPRArg {
|
||||
double d[2];
|
||||
float f[4];
|
||||
uint8_t b[16];
|
||||
uint16_t s[8];
|
||||
int i[4];
|
||||
int64_t l[2];
|
||||
} FPRArg;
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
|
||||
#elif LJ_TARGET_ARM
|
||||
|
||||
#define CCALL_NARG_GPR 4
|
||||
#define CCALL_NRET_GPR 2 /* For softfp double. */
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define CCALL_NARG_FPR 0
|
||||
#define CCALL_NRET_FPR 0
|
||||
#else
|
||||
#define CCALL_NARG_FPR 8
|
||||
#define CCALL_NRET_FPR 4
|
||||
#endif
|
||||
#define CCALL_SPS_FREE 0
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
typedef union FPRArg {
|
||||
double d;
|
||||
float f[2];
|
||||
} FPRArg;
|
||||
|
||||
#elif LJ_TARGET_ARM64
|
||||
|
||||
#define CCALL_NARG_GPR 8
|
||||
#define CCALL_NRET_GPR 2
|
||||
#define CCALL_NARG_FPR 8
|
||||
#define CCALL_NRET_FPR 4
|
||||
#define CCALL_SPS_FREE 0
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
typedef union FPRArg {
|
||||
double d;
|
||||
struct { LJ_ENDIAN_LOHI(float f; , float g;) };
|
||||
struct { LJ_ENDIAN_LOHI(uint32_t lo; , uint32_t hi;) };
|
||||
} FPRArg;
|
||||
|
||||
#elif LJ_TARGET_PPC
|
||||
|
||||
#define CCALL_NARG_GPR 8
|
||||
#define CCALL_NARG_FPR 8
|
||||
#define CCALL_NRET_GPR 4 /* For complex double. */
|
||||
#define CCALL_NRET_FPR 1
|
||||
#define CCALL_SPS_EXTRA 4
|
||||
#define CCALL_SPS_FREE 0
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
typedef double FPRArg;
|
||||
|
||||
#elif LJ_TARGET_MIPS32
|
||||
|
||||
#define CCALL_NARG_GPR 4
|
||||
#define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 2)
|
||||
#define CCALL_NRET_GPR (LJ_ABI_SOFTFP ? 4 : 2)
|
||||
#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 2)
|
||||
#define CCALL_SPS_EXTRA 7
|
||||
#define CCALL_SPS_FREE 1
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
typedef union FPRArg {
|
||||
double d;
|
||||
struct { LJ_ENDIAN_LOHI(float f; , float g;) };
|
||||
} FPRArg;
|
||||
|
||||
#elif LJ_TARGET_MIPS64
|
||||
|
||||
/* FP args are positional and overlay the GPR array. */
|
||||
#define CCALL_NARG_GPR 8
|
||||
#define CCALL_NARG_FPR 0
|
||||
#define CCALL_NRET_GPR 2
|
||||
#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 2)
|
||||
#define CCALL_SPS_EXTRA 3
|
||||
#define CCALL_SPS_FREE 1
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
typedef union FPRArg {
|
||||
double d;
|
||||
struct { LJ_ENDIAN_LOHI(float f; , float g;) };
|
||||
} FPRArg;
|
||||
|
||||
#else
|
||||
#error "Missing calling convention definitions for this architecture"
|
||||
#endif
|
||||
|
||||
#ifndef CCALL_SPS_EXTRA
|
||||
#define CCALL_SPS_EXTRA 0
|
||||
#endif
|
||||
#ifndef CCALL_VECTOR_REG
|
||||
#define CCALL_VECTOR_REG 0
|
||||
#endif
|
||||
#ifndef CCALL_ALIGN_STACKARG
|
||||
#define CCALL_ALIGN_STACKARG 1
|
||||
#endif
|
||||
#ifndef CCALL_ALIGN_CALLSTATE
|
||||
#define CCALL_ALIGN_CALLSTATE 8
|
||||
#endif
|
||||
|
||||
#define CCALL_NUM_GPR \
|
||||
(CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
|
||||
#define CCALL_NUM_FPR \
|
||||
(CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
|
||||
|
||||
/* Check against constants in lj_ctype.h. */
|
||||
LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
|
||||
LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
|
||||
|
||||
#define CCALL_MAXSTACK 32
|
||||
|
||||
/* -- C call state -------------------------------------------------------- */
|
||||
|
||||
typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
|
||||
void (*func)(void); /* Pointer to called function. */
|
||||
uint32_t spadj; /* Stack pointer adjustment. */
|
||||
uint8_t nsp; /* Number of stack slots. */
|
||||
uint8_t retref; /* Return value by reference. */
|
||||
#if LJ_TARGET_X64
|
||||
uint8_t ngpr; /* Number of arguments in GPRs. */
|
||||
uint8_t nfpr; /* Number of arguments in FPRs. */
|
||||
#elif LJ_TARGET_X86
|
||||
uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
|
||||
#elif LJ_TARGET_ARM64
|
||||
void *retp; /* Aggregate return pointer in x8. */
|
||||
#elif LJ_TARGET_PPC
|
||||
uint8_t nfpr; /* Number of arguments in FPRs. */
|
||||
#endif
|
||||
#if LJ_32
|
||||
int32_t align1;
|
||||
#endif
|
||||
#if CCALL_NUM_FPR
|
||||
FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
|
||||
#endif
|
||||
GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
|
||||
GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
|
||||
} CCallState;
|
||||
|
||||
/* -- C call handling ----------------------------------------------------- */
|
||||
|
||||
/* Really belongs to lj_vm.h. */
|
||||
LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
|
||||
|
||||
LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
|
||||
LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
** FFI C callback handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CCALLBACK_H
|
||||
#define _LJ_CCALLBACK_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_ctype.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* Really belongs to lj_vm.h. */
|
||||
LJ_ASMF void lj_vm_ffi_callback(void);
|
||||
|
||||
LJ_FUNC MSize lj_ccallback_ptr2slot(CTState *cts, void *p);
|
||||
LJ_FUNCA lua_State * LJ_FASTCALL lj_ccallback_enter(CTState *cts, void *cf);
|
||||
LJ_FUNCA void LJ_FASTCALL lj_ccallback_leave(CTState *cts, TValue *o);
|
||||
LJ_FUNC void *lj_ccallback_new(CTState *cts, CType *ct, GCfunc *fn);
|
||||
LJ_FUNC void lj_ccallback_mcode_free(CTState *cts);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
** C type conversions.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CCONV_H
|
||||
#define _LJ_CCONV_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_ctype.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* Compressed C type index. ORDER CCX. */
|
||||
enum {
|
||||
CCX_B, /* Bool. */
|
||||
CCX_I, /* Integer. */
|
||||
CCX_F, /* Floating-point number. */
|
||||
CCX_C, /* Complex. */
|
||||
CCX_V, /* Vector. */
|
||||
CCX_P, /* Pointer. */
|
||||
CCX_A, /* Refarray. */
|
||||
CCX_S /* Struct/union. */
|
||||
};
|
||||
|
||||
/* Convert C type info to compressed C type index. ORDER CT. ORDER CCX. */
|
||||
static LJ_AINLINE uint32_t cconv_idx(CTInfo info)
|
||||
{
|
||||
uint32_t idx = ((info >> 26) & 15u); /* Dispatch bits. */
|
||||
lua_assert(ctype_type(info) <= CT_MAYCONVERT);
|
||||
#if LJ_64
|
||||
idx = ((uint32_t)(U64x(f436fff5,fff7f021) >> 4*idx) & 15u);
|
||||
#else
|
||||
idx = (((idx < 8 ? 0xfff7f021u : 0xf436fff5) >> 4*(idx & 7u)) & 15u);
|
||||
#endif
|
||||
lua_assert(idx < 8);
|
||||
return idx;
|
||||
}
|
||||
|
||||
#define cconv_idx2(dinfo, sinfo) \
|
||||
((cconv_idx((dinfo)) << 3) + cconv_idx((sinfo)))
|
||||
|
||||
#define CCX(dst, src) ((CCX_##dst << 3) + CCX_##src)
|
||||
|
||||
/* Conversion flags. */
|
||||
#define CCF_CAST 0x00000001u
|
||||
#define CCF_FROMTV 0x00000002u
|
||||
#define CCF_SAME 0x00000004u
|
||||
#define CCF_IGNQUAL 0x00000008u
|
||||
|
||||
#define CCF_ARG_SHIFT 8
|
||||
#define CCF_ARG(n) ((n) << CCF_ARG_SHIFT)
|
||||
#define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT)
|
||||
|
||||
LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags);
|
||||
LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
|
||||
uint8_t *dp, uint8_t *sp, CTInfo flags);
|
||||
LJ_FUNC int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
|
||||
TValue *o, uint8_t *sp);
|
||||
LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp);
|
||||
LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d,
|
||||
uint8_t *dp, TValue *o, CTInfo flags);
|
||||
LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o);
|
||||
LJ_FUNC int lj_cconv_multi_init(CTState *cts, CType *d, TValue *o);
|
||||
LJ_FUNC void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
|
||||
uint8_t *dp, TValue *o, MSize len);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
** C data management.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CDATA_H
|
||||
#define _LJ_CDATA_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_ctype.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* Get C data pointer. */
|
||||
static LJ_AINLINE void *cdata_getptr(void *p, CTSize sz)
|
||||
{
|
||||
if (LJ_64 && sz == 4) { /* Support 32 bit pointers on 64 bit targets. */
|
||||
return ((void *)(uintptr_t)*(uint32_t *)p);
|
||||
} else {
|
||||
lua_assert(sz == CTSIZE_PTR);
|
||||
return *(void **)p;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set C data pointer. */
|
||||
static LJ_AINLINE void cdata_setptr(void *p, CTSize sz, const void *v)
|
||||
{
|
||||
if (LJ_64 && sz == 4) { /* Support 32 bit pointers on 64 bit targets. */
|
||||
*(uint32_t *)p = (uint32_t)(uintptr_t)v;
|
||||
} else {
|
||||
lua_assert(sz == CTSIZE_PTR);
|
||||
*(void **)p = (void *)v;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate fixed-size C data object. */
|
||||
static LJ_AINLINE GCcdata *lj_cdata_new(CTState *cts, CTypeID id, CTSize sz)
|
||||
{
|
||||
GCcdata *cd;
|
||||
#ifdef LUA_USE_ASSERT
|
||||
CType *ct = ctype_raw(cts, id);
|
||||
lua_assert((ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR) == sz);
|
||||
#endif
|
||||
cd = (GCcdata *)lj_mem_newgco(cts->L, sizeof(GCcdata) + sz);
|
||||
cd->gct = ~LJ_TCDATA;
|
||||
cd->ctypeid = ctype_check(cts, id);
|
||||
return cd;
|
||||
}
|
||||
|
||||
/* Variant which works without a valid CTState. */
|
||||
static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz)
|
||||
{
|
||||
GCcdata *cd = (GCcdata *)lj_mem_newgco(L, sizeof(GCcdata) + sz);
|
||||
cd->gct = ~LJ_TCDATA;
|
||||
cd->ctypeid = id;
|
||||
return cd;
|
||||
}
|
||||
|
||||
LJ_FUNC GCcdata *lj_cdata_newref(CTState *cts, const void *pp, CTypeID id);
|
||||
LJ_FUNC GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz,
|
||||
CTSize align);
|
||||
LJ_FUNC GCcdata *lj_cdata_newx(CTState *cts, CTypeID id, CTSize sz,
|
||||
CTInfo info);
|
||||
|
||||
LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd);
|
||||
LJ_FUNC void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj,
|
||||
uint32_t it);
|
||||
|
||||
LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key,
|
||||
uint8_t **pp, CTInfo *qual);
|
||||
LJ_FUNC int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp);
|
||||
LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o,
|
||||
CTInfo qual);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
** Character types.
|
||||
** Donated to the public domain.
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CHAR_H
|
||||
#define _LJ_CHAR_H
|
||||
|
||||
#include "lj_def.h"
|
||||
|
||||
#define LJ_CHAR_CNTRL 0x01
|
||||
#define LJ_CHAR_SPACE 0x02
|
||||
#define LJ_CHAR_PUNCT 0x04
|
||||
#define LJ_CHAR_DIGIT 0x08
|
||||
#define LJ_CHAR_XDIGIT 0x10
|
||||
#define LJ_CHAR_UPPER 0x20
|
||||
#define LJ_CHAR_LOWER 0x40
|
||||
#define LJ_CHAR_IDENT 0x80
|
||||
#define LJ_CHAR_ALPHA (LJ_CHAR_LOWER|LJ_CHAR_UPPER)
|
||||
#define LJ_CHAR_ALNUM (LJ_CHAR_ALPHA|LJ_CHAR_DIGIT)
|
||||
#define LJ_CHAR_GRAPH (LJ_CHAR_ALNUM|LJ_CHAR_PUNCT)
|
||||
|
||||
/* Only pass -1 or 0..255 to these macros. Never pass a signed char! */
|
||||
#define lj_char_isa(c, t) ((lj_char_bits+1)[(c)] & t)
|
||||
#define lj_char_iscntrl(c) lj_char_isa((c), LJ_CHAR_CNTRL)
|
||||
#define lj_char_isspace(c) lj_char_isa((c), LJ_CHAR_SPACE)
|
||||
#define lj_char_ispunct(c) lj_char_isa((c), LJ_CHAR_PUNCT)
|
||||
#define lj_char_isdigit(c) lj_char_isa((c), LJ_CHAR_DIGIT)
|
||||
#define lj_char_isxdigit(c) lj_char_isa((c), LJ_CHAR_XDIGIT)
|
||||
#define lj_char_isupper(c) lj_char_isa((c), LJ_CHAR_UPPER)
|
||||
#define lj_char_islower(c) lj_char_isa((c), LJ_CHAR_LOWER)
|
||||
#define lj_char_isident(c) lj_char_isa((c), LJ_CHAR_IDENT)
|
||||
#define lj_char_isalpha(c) lj_char_isa((c), LJ_CHAR_ALPHA)
|
||||
#define lj_char_isalnum(c) lj_char_isa((c), LJ_CHAR_ALNUM)
|
||||
#define lj_char_isgraph(c) lj_char_isa((c), LJ_CHAR_GRAPH)
|
||||
|
||||
#define lj_char_toupper(c) ((c) - (lj_char_islower(c) >> 1))
|
||||
#define lj_char_tolower(c) ((c) + lj_char_isupper(c))
|
||||
|
||||
LJ_DATA const uint8_t lj_char_bits[257];
|
||||
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
** FFI C library loader.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CLIB_H
|
||||
#define _LJ_CLIB_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* Namespace for C library indexing. */
|
||||
#define CLNS_INDEX ((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
|
||||
|
||||
/* C library namespace. */
|
||||
typedef struct CLibrary {
|
||||
void *handle; /* Opaque handle for dynamic library loader. */
|
||||
GCtab *cache; /* Cache for resolved symbols. Anchored in ud->env. */
|
||||
} CLibrary;
|
||||
|
||||
LJ_FUNC TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name);
|
||||
LJ_FUNC void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global);
|
||||
LJ_FUNC void lj_clib_unload(CLibrary *cl);
|
||||
LJ_FUNC void lj_clib_default(lua_State *L, GCtab *mt);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
** C declaration parser.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CPARSE_H
|
||||
#define _LJ_CPARSE_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_ctype.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* C parser limits. */
|
||||
#define CPARSE_MAX_BUF 32768 /* Max. token buffer size. */
|
||||
#define CPARSE_MAX_DECLSTACK 100 /* Max. declaration stack depth. */
|
||||
#define CPARSE_MAX_DECLDEPTH 20 /* Max. recursive declaration depth. */
|
||||
#define CPARSE_MAX_PACKSTACK 7 /* Max. pack pragma stack depth. */
|
||||
|
||||
/* Flags for C parser mode. */
|
||||
#define CPARSE_MODE_MULTI 1 /* Process multiple declarations. */
|
||||
#define CPARSE_MODE_ABSTRACT 2 /* Accept abstract declarators. */
|
||||
#define CPARSE_MODE_DIRECT 4 /* Accept direct declarators. */
|
||||
#define CPARSE_MODE_FIELD 8 /* Accept field width in bits, too. */
|
||||
#define CPARSE_MODE_NOIMPLICIT 16 /* Reject implicit declarations. */
|
||||
#define CPARSE_MODE_SKIP 32 /* Skip definitions, ignore errors. */
|
||||
|
||||
typedef int CPChar; /* C parser character. Unsigned ext. from char. */
|
||||
typedef int CPToken; /* C parser token. */
|
||||
|
||||
/* C parser internal value representation. */
|
||||
typedef struct CPValue {
|
||||
union {
|
||||
int32_t i32; /* Value for CTID_INT32. */
|
||||
uint32_t u32; /* Value for CTID_UINT32. */
|
||||
};
|
||||
CTypeID id; /* C Type ID of the value. */
|
||||
} CPValue;
|
||||
|
||||
/* C parser state. */
|
||||
typedef struct CPState {
|
||||
CPChar c; /* Current character. */
|
||||
CPToken tok; /* Current token. */
|
||||
CPValue val; /* Token value. */
|
||||
GCstr *str; /* Interned string of identifier/keyword. */
|
||||
CType *ct; /* C type table entry. */
|
||||
const char *p; /* Current position in input buffer. */
|
||||
SBuf sb; /* String buffer for tokens. */
|
||||
lua_State *L; /* Lua state. */
|
||||
CTState *cts; /* C type state. */
|
||||
TValue *param; /* C type parameters. */
|
||||
const char *srcname; /* Current source name. */
|
||||
BCLine linenumber; /* Input line counter. */
|
||||
int depth; /* Recursive declaration depth. */
|
||||
uint32_t tmask; /* Type mask for next identifier. */
|
||||
uint32_t mode; /* C parser mode. */
|
||||
uint8_t packstack[CPARSE_MAX_PACKSTACK]; /* Stack for pack pragmas. */
|
||||
uint8_t curpack; /* Current position in pack pragma stack. */
|
||||
} CPState;
|
||||
|
||||
LJ_FUNC int lj_cparse(CPState *cp);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
** Trace recorder for C data operations.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CRECORD_H
|
||||
#define _LJ_CRECORD_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_jit.h"
|
||||
#include "lj_ffrecord.h"
|
||||
|
||||
#if LJ_HASJIT && LJ_HASFFI
|
||||
LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd);
|
||||
|
||||
LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd);
|
||||
LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr);
|
||||
|
||||
LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,461 +0,0 @@
|
||||
/*
|
||||
** C type management.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CTYPE_H
|
||||
#define _LJ_CTYPE_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
/* -- C type definitions -------------------------------------------------- */
|
||||
|
||||
/* C type numbers. Highest 4 bits of C type info. ORDER CT. */
|
||||
enum {
|
||||
/* Externally visible types. */
|
||||
CT_NUM, /* Integer or floating-point numbers. */
|
||||
CT_STRUCT, /* Struct or union. */
|
||||
CT_PTR, /* Pointer or reference. */
|
||||
CT_ARRAY, /* Array or complex type. */
|
||||
CT_MAYCONVERT = CT_ARRAY,
|
||||
CT_VOID, /* Void type. */
|
||||
CT_ENUM, /* Enumeration. */
|
||||
CT_HASSIZE = CT_ENUM, /* Last type where ct->size holds the actual size. */
|
||||
CT_FUNC, /* Function. */
|
||||
CT_TYPEDEF, /* Typedef. */
|
||||
CT_ATTRIB, /* Miscellaneous attributes. */
|
||||
/* Internal element types. */
|
||||
CT_FIELD, /* Struct/union field or function parameter. */
|
||||
CT_BITFIELD, /* Struct/union bitfield. */
|
||||
CT_CONSTVAL, /* Constant value. */
|
||||
CT_EXTERN, /* External reference. */
|
||||
CT_KW /* Keyword. */
|
||||
};
|
||||
|
||||
LJ_STATIC_ASSERT(((int)CT_PTR & (int)CT_ARRAY) == CT_PTR);
|
||||
LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT);
|
||||
|
||||
/*
|
||||
** ---------- info ------------
|
||||
** |type flags... A cid | size | sib | next | name |
|
||||
** +----------------------------+--------+-------+-------+-------+--
|
||||
** |NUM BFcvUL.. A | size | | type | |
|
||||
** |STRUCT ..cvU..V A | size | field | name? | name? |
|
||||
** |PTR ..cvR... A cid | size | | type | |
|
||||
** |ARRAY VCcv...V A cid | size | | type | |
|
||||
** |VOID ..cv.... A | size | | type | |
|
||||
** |ENUM A cid | size | const | name? | name? |
|
||||
** |FUNC ....VS.. cc cid | nargs | field | name? | name? |
|
||||
** |TYPEDEF cid | | | name | name |
|
||||
** |ATTRIB attrnum cid | attr | sib? | type? | |
|
||||
** |FIELD cid | offset | field | | name? |
|
||||
** |BITFIELD B.cvU csz bsz pos | offset | field | | name? |
|
||||
** |CONSTVAL c cid | value | const | name | name |
|
||||
** |EXTERN cid | | sib? | name | name |
|
||||
** |KW tok | size | | name | name |
|
||||
** +----------------------------+--------+-------+-------+-------+--
|
||||
** ^^ ^^--- bits used for C type conversion dispatch
|
||||
*/
|
||||
|
||||
/* C type info flags. TFFArrrr */
|
||||
#define CTF_BOOL 0x08000000u /* Boolean: NUM, BITFIELD. */
|
||||
#define CTF_FP 0x04000000u /* Floating-point: NUM. */
|
||||
#define CTF_CONST 0x02000000u /* Const qualifier. */
|
||||
#define CTF_VOLATILE 0x01000000u /* Volatile qualifier. */
|
||||
#define CTF_UNSIGNED 0x00800000u /* Unsigned: NUM, BITFIELD. */
|
||||
#define CTF_LONG 0x00400000u /* Long: NUM. */
|
||||
#define CTF_VLA 0x00100000u /* Variable-length: ARRAY, STRUCT. */
|
||||
#define CTF_REF 0x00800000u /* Reference: PTR. */
|
||||
#define CTF_VECTOR 0x08000000u /* Vector: ARRAY. */
|
||||
#define CTF_COMPLEX 0x04000000u /* Complex: ARRAY. */
|
||||
#define CTF_UNION 0x00800000u /* Union: STRUCT. */
|
||||
#define CTF_VARARG 0x00800000u /* Vararg: FUNC. */
|
||||
#define CTF_SSEREGPARM 0x00400000u /* SSE register parameters: FUNC. */
|
||||
|
||||
#define CTF_QUAL (CTF_CONST|CTF_VOLATILE)
|
||||
#define CTF_ALIGN (CTMASK_ALIGN<<CTSHIFT_ALIGN)
|
||||
#define CTF_UCHAR ((char)-1 > 0 ? CTF_UNSIGNED : 0)
|
||||
|
||||
/* Flags used in parser. .F.Ammvf cp->attr */
|
||||
#define CTFP_ALIGNED 0x00000001u /* cp->attr + ALIGN */
|
||||
#define CTFP_PACKED 0x00000002u /* cp->attr */
|
||||
/* ...C...f cp->fattr */
|
||||
#define CTFP_CCONV 0x00000001u /* cp->fattr + CCONV/[SSE]REGPARM */
|
||||
|
||||
/* C type info bitfields. */
|
||||
#define CTMASK_CID 0x0000ffffu /* Max. 65536 type IDs. */
|
||||
#define CTMASK_NUM 0xf0000000u /* Max. 16 type numbers. */
|
||||
#define CTSHIFT_NUM 28
|
||||
#define CTMASK_ALIGN 15 /* Max. alignment is 2^15. */
|
||||
#define CTSHIFT_ALIGN 16
|
||||
#define CTMASK_ATTRIB 255 /* Max. 256 attributes. */
|
||||
#define CTSHIFT_ATTRIB 16
|
||||
#define CTMASK_CCONV 3 /* Max. 4 calling conventions. */
|
||||
#define CTSHIFT_CCONV 16
|
||||
#define CTMASK_REGPARM 3 /* Max. 0-3 regparms. */
|
||||
#define CTSHIFT_REGPARM 18
|
||||
/* Bitfields only used in parser. */
|
||||
#define CTMASK_VSIZEP 15 /* Max. vector size is 2^15. */
|
||||
#define CTSHIFT_VSIZEP 4
|
||||
#define CTMASK_MSIZEP 255 /* Max. type size (via mode) is 128. */
|
||||
#define CTSHIFT_MSIZEP 8
|
||||
|
||||
/* Info bits for BITFIELD. Max. size of bitfield is 64 bits. */
|
||||
#define CTBSZ_MAX 32 /* Max. size of bitfield is 32 bit. */
|
||||
#define CTBSZ_FIELD 127 /* Temp. marker for regular field. */
|
||||
#define CTMASK_BITPOS 127
|
||||
#define CTMASK_BITBSZ 127
|
||||
#define CTMASK_BITCSZ 127
|
||||
#define CTSHIFT_BITPOS 0
|
||||
#define CTSHIFT_BITBSZ 8
|
||||
#define CTSHIFT_BITCSZ 16
|
||||
|
||||
#define CTF_INSERT(info, field, val) \
|
||||
info = (info & ~(CTMASK_##field<<CTSHIFT_##field)) | \
|
||||
(((CTSize)(val) & CTMASK_##field) << CTSHIFT_##field)
|
||||
|
||||
/* Calling conventions. ORDER CC */
|
||||
enum { CTCC_CDECL, CTCC_THISCALL, CTCC_FASTCALL, CTCC_STDCALL };
|
||||
|
||||
/* Attribute numbers. */
|
||||
enum {
|
||||
CTA_NONE, /* Ignored attribute. Must be zero. */
|
||||
CTA_QUAL, /* Unmerged qualifiers. */
|
||||
CTA_ALIGN, /* Alignment override. */
|
||||
CTA_SUBTYPE, /* Transparent sub-type. */
|
||||
CTA_REDIR, /* Redirected symbol name. */
|
||||
CTA_BAD, /* To catch bad IDs. */
|
||||
CTA__MAX
|
||||
};
|
||||
|
||||
/* Special sizes. */
|
||||
#define CTSIZE_INVALID 0xffffffffu
|
||||
|
||||
typedef uint32_t CTInfo; /* Type info. */
|
||||
typedef uint32_t CTSize; /* Type size. */
|
||||
typedef uint32_t CTypeID; /* Type ID. */
|
||||
typedef uint16_t CTypeID1; /* Minimum-sized type ID. */
|
||||
|
||||
/* C type table element. */
|
||||
typedef struct CType {
|
||||
CTInfo info; /* Type info. */
|
||||
CTSize size; /* Type size or other info. */
|
||||
CTypeID1 sib; /* Sibling element. */
|
||||
CTypeID1 next; /* Next element in hash chain. */
|
||||
GCRef name; /* Element name (GCstr). */
|
||||
} CType;
|
||||
|
||||
#define CTHASH_SIZE 128 /* Number of hash anchors. */
|
||||
#define CTHASH_MASK (CTHASH_SIZE-1)
|
||||
|
||||
/* Simplify target-specific configuration. Checked in lj_ccall.h. */
|
||||
#define CCALL_MAX_GPR 8
|
||||
#define CCALL_MAX_FPR 8
|
||||
|
||||
typedef LJ_ALIGN(8) union FPRCBArg { double d; float f[2]; } FPRCBArg;
|
||||
|
||||
/* C callback state. Defined here, to avoid dragging in lj_ccall.h. */
|
||||
|
||||
typedef LJ_ALIGN(8) struct CCallback {
|
||||
FPRCBArg fpr[CCALL_MAX_FPR]; /* Arguments/results in FPRs. */
|
||||
intptr_t gpr[CCALL_MAX_GPR]; /* Arguments/results in GPRs. */
|
||||
intptr_t *stack; /* Pointer to arguments on stack. */
|
||||
void *mcode; /* Machine code for callback func. pointers. */
|
||||
CTypeID1 *cbid; /* Callback type table. */
|
||||
MSize sizeid; /* Size of callback type table. */
|
||||
MSize topid; /* Highest unused callback type table slot. */
|
||||
MSize slot; /* Current callback slot. */
|
||||
} CCallback;
|
||||
|
||||
/* C type state. */
|
||||
typedef struct CTState {
|
||||
CType *tab; /* C type table. */
|
||||
CTypeID top; /* Current top of C type table. */
|
||||
MSize sizetab; /* Size of C type table. */
|
||||
lua_State *L; /* Lua state (needed for errors and allocations). */
|
||||
global_State *g; /* Global state. */
|
||||
GCtab *finalizer; /* Map of cdata to finalizer. */
|
||||
GCtab *miscmap; /* Map of -CTypeID to metatable and cb slot to func. */
|
||||
CCallback cb; /* Temporary callback state. */
|
||||
CTypeID1 hash[CTHASH_SIZE]; /* Hash anchors for C type table. */
|
||||
} CTState;
|
||||
|
||||
#define CTINFO(ct, flags) (((CTInfo)(ct) << CTSHIFT_NUM) + (flags))
|
||||
#define CTALIGN(al) ((CTSize)(al) << CTSHIFT_ALIGN)
|
||||
#define CTATTRIB(at) ((CTInfo)(at) << CTSHIFT_ATTRIB)
|
||||
|
||||
#define ctype_type(info) ((info) >> CTSHIFT_NUM)
|
||||
#define ctype_cid(info) ((CTypeID)((info) & CTMASK_CID))
|
||||
#define ctype_align(info) (((info) >> CTSHIFT_ALIGN) & CTMASK_ALIGN)
|
||||
#define ctype_attrib(info) (((info) >> CTSHIFT_ATTRIB) & CTMASK_ATTRIB)
|
||||
#define ctype_bitpos(info) (((info) >> CTSHIFT_BITPOS) & CTMASK_BITPOS)
|
||||
#define ctype_bitbsz(info) (((info) >> CTSHIFT_BITBSZ) & CTMASK_BITBSZ)
|
||||
#define ctype_bitcsz(info) (((info) >> CTSHIFT_BITCSZ) & CTMASK_BITCSZ)
|
||||
#define ctype_vsizeP(info) (((info) >> CTSHIFT_VSIZEP) & CTMASK_VSIZEP)
|
||||
#define ctype_msizeP(info) (((info) >> CTSHIFT_MSIZEP) & CTMASK_MSIZEP)
|
||||
#define ctype_cconv(info) (((info) >> CTSHIFT_CCONV) & CTMASK_CCONV)
|
||||
|
||||
/* Simple type checks. */
|
||||
#define ctype_isnum(info) (ctype_type((info)) == CT_NUM)
|
||||
#define ctype_isvoid(info) (ctype_type((info)) == CT_VOID)
|
||||
#define ctype_isptr(info) (ctype_type((info)) == CT_PTR)
|
||||
#define ctype_isarray(info) (ctype_type((info)) == CT_ARRAY)
|
||||
#define ctype_isstruct(info) (ctype_type((info)) == CT_STRUCT)
|
||||
#define ctype_isfunc(info) (ctype_type((info)) == CT_FUNC)
|
||||
#define ctype_isenum(info) (ctype_type((info)) == CT_ENUM)
|
||||
#define ctype_istypedef(info) (ctype_type((info)) == CT_TYPEDEF)
|
||||
#define ctype_isattrib(info) (ctype_type((info)) == CT_ATTRIB)
|
||||
#define ctype_isfield(info) (ctype_type((info)) == CT_FIELD)
|
||||
#define ctype_isbitfield(info) (ctype_type((info)) == CT_BITFIELD)
|
||||
#define ctype_isconstval(info) (ctype_type((info)) == CT_CONSTVAL)
|
||||
#define ctype_isextern(info) (ctype_type((info)) == CT_EXTERN)
|
||||
#define ctype_hassize(info) (ctype_type((info)) <= CT_HASSIZE)
|
||||
|
||||
/* Combined type and flag checks. */
|
||||
#define ctype_isinteger(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_BOOL|CTF_FP)) == CTINFO(CT_NUM, 0))
|
||||
#define ctype_isinteger_or_bool(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_FP)) == CTINFO(CT_NUM, 0))
|
||||
#define ctype_isbool(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_BOOL)) == CTINFO(CT_NUM, CTF_BOOL))
|
||||
#define ctype_isfp(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_FP)) == CTINFO(CT_NUM, CTF_FP))
|
||||
|
||||
#define ctype_ispointer(info) \
|
||||
((ctype_type(info) >> 1) == (CT_PTR >> 1)) /* Pointer or array. */
|
||||
#define ctype_isref(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_REF)) == CTINFO(CT_PTR, CTF_REF))
|
||||
|
||||
#define ctype_isrefarray(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_VECTOR|CTF_COMPLEX)) == CTINFO(CT_ARRAY, 0))
|
||||
#define ctype_isvector(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_VECTOR)) == CTINFO(CT_ARRAY, CTF_VECTOR))
|
||||
#define ctype_iscomplex(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_COMPLEX)) == CTINFO(CT_ARRAY, CTF_COMPLEX))
|
||||
|
||||
#define ctype_isvltype(info) \
|
||||
(((info) & ((CTMASK_NUM|CTF_VLA) - (2u<<CTSHIFT_NUM))) == \
|
||||
CTINFO(CT_STRUCT, CTF_VLA)) /* VL array or VL struct. */
|
||||
#define ctype_isvlarray(info) \
|
||||
(((info) & (CTMASK_NUM|CTF_VLA)) == CTINFO(CT_ARRAY, CTF_VLA))
|
||||
|
||||
#define ctype_isxattrib(info, at) \
|
||||
(((info) & (CTMASK_NUM|CTATTRIB(CTMASK_ATTRIB))) == \
|
||||
CTINFO(CT_ATTRIB, CTATTRIB(at)))
|
||||
|
||||
/* Target-dependent sizes and alignments. */
|
||||
#if LJ_64
|
||||
#define CTSIZE_PTR 8
|
||||
#define CTALIGN_PTR CTALIGN(3)
|
||||
#else
|
||||
#define CTSIZE_PTR 4
|
||||
#define CTALIGN_PTR CTALIGN(2)
|
||||
#endif
|
||||
|
||||
#define CTINFO_REF(ref) \
|
||||
CTINFO(CT_PTR, (CTF_CONST|CTF_REF|CTALIGN_PTR) + (ref))
|
||||
|
||||
#define CT_MEMALIGN 3 /* Alignment guaranteed by memory allocator. */
|
||||
|
||||
/* -- Predefined types ---------------------------------------------------- */
|
||||
|
||||
/* Target-dependent types. */
|
||||
#if LJ_TARGET_PPC
|
||||
#define CTTYDEFP(_) \
|
||||
_(LINT32, 4, CT_NUM, CTF_LONG|CTALIGN(2))
|
||||
#else
|
||||
#define CTTYDEFP(_)
|
||||
#endif
|
||||
|
||||
/* Common types. */
|
||||
#define CTTYDEF(_) \
|
||||
_(NONE, 0, CT_ATTRIB, CTATTRIB(CTA_BAD)) \
|
||||
_(VOID, -1, CT_VOID, CTALIGN(0)) \
|
||||
_(CVOID, -1, CT_VOID, CTF_CONST|CTALIGN(0)) \
|
||||
_(BOOL, 1, CT_NUM, CTF_BOOL|CTF_UNSIGNED|CTALIGN(0)) \
|
||||
_(CCHAR, 1, CT_NUM, CTF_CONST|CTF_UCHAR|CTALIGN(0)) \
|
||||
_(INT8, 1, CT_NUM, CTALIGN(0)) \
|
||||
_(UINT8, 1, CT_NUM, CTF_UNSIGNED|CTALIGN(0)) \
|
||||
_(INT16, 2, CT_NUM, CTALIGN(1)) \
|
||||
_(UINT16, 2, CT_NUM, CTF_UNSIGNED|CTALIGN(1)) \
|
||||
_(INT32, 4, CT_NUM, CTALIGN(2)) \
|
||||
_(UINT32, 4, CT_NUM, CTF_UNSIGNED|CTALIGN(2)) \
|
||||
_(INT64, 8, CT_NUM, CTF_LONG|CTALIGN(3)) \
|
||||
_(UINT64, 8, CT_NUM, CTF_UNSIGNED|CTF_LONG|CTALIGN(3)) \
|
||||
_(FLOAT, 4, CT_NUM, CTF_FP|CTALIGN(2)) \
|
||||
_(DOUBLE, 8, CT_NUM, CTF_FP|CTALIGN(3)) \
|
||||
_(COMPLEX_FLOAT, 8, CT_ARRAY, CTF_COMPLEX|CTALIGN(2)|CTID_FLOAT) \
|
||||
_(COMPLEX_DOUBLE, 16, CT_ARRAY, CTF_COMPLEX|CTALIGN(3)|CTID_DOUBLE) \
|
||||
_(P_VOID, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_VOID) \
|
||||
_(P_CVOID, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_CVOID) \
|
||||
_(P_CCHAR, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_CCHAR) \
|
||||
_(A_CCHAR, -1, CT_ARRAY, CTF_CONST|CTALIGN(0)|CTID_CCHAR) \
|
||||
_(CTYPEID, 4, CT_ENUM, CTALIGN(2)|CTID_INT32) \
|
||||
CTTYDEFP(_) \
|
||||
/* End of type list. */
|
||||
|
||||
/* Public predefined type IDs. */
|
||||
enum {
|
||||
#define CTTYIDDEF(id, sz, ct, info) CTID_##id,
|
||||
CTTYDEF(CTTYIDDEF)
|
||||
#undef CTTYIDDEF
|
||||
/* Predefined typedefs and keywords follow. */
|
||||
CTID_MAX = 65536
|
||||
};
|
||||
|
||||
/* Target-dependent type IDs. */
|
||||
#if LJ_64
|
||||
#define CTID_INT_PSZ CTID_INT64
|
||||
#define CTID_UINT_PSZ CTID_UINT64
|
||||
#else
|
||||
#define CTID_INT_PSZ CTID_INT32
|
||||
#define CTID_UINT_PSZ CTID_UINT32
|
||||
#endif
|
||||
|
||||
#if LJ_ABI_WIN
|
||||
#define CTID_WCHAR CTID_UINT16
|
||||
#elif LJ_TARGET_PPC
|
||||
#define CTID_WCHAR CTID_LINT32
|
||||
#else
|
||||
#define CTID_WCHAR CTID_INT32
|
||||
#endif
|
||||
|
||||
/* -- C tokens and keywords ----------------------------------------------- */
|
||||
|
||||
/* C lexer keywords. */
|
||||
#define CTOKDEF(_) \
|
||||
_(IDENT, "<identifier>") _(STRING, "<string>") \
|
||||
_(INTEGER, "<integer>") _(EOF, "<eof>") \
|
||||
_(OROR, "||") _(ANDAND, "&&") _(EQ, "==") _(NE, "!=") \
|
||||
_(LE, "<=") _(GE, ">=") _(SHL, "<<") _(SHR, ">>") _(DEREF, "->")
|
||||
|
||||
/* Simple declaration specifiers. */
|
||||
#define CDSDEF(_) \
|
||||
_(VOID) _(BOOL) _(CHAR) _(INT) _(FP) \
|
||||
_(LONG) _(LONGLONG) _(SHORT) _(COMPLEX) _(SIGNED) _(UNSIGNED) \
|
||||
_(CONST) _(VOLATILE) _(RESTRICT) _(INLINE) \
|
||||
_(TYPEDEF) _(EXTERN) _(STATIC) _(AUTO) _(REGISTER)
|
||||
|
||||
/* C keywords. */
|
||||
#define CKWDEF(_) \
|
||||
CDSDEF(_) _(EXTENSION) _(ASM) _(ATTRIBUTE) \
|
||||
_(DECLSPEC) _(CCDECL) _(PTRSZ) \
|
||||
_(STRUCT) _(UNION) _(ENUM) \
|
||||
_(SIZEOF) _(ALIGNOF)
|
||||
|
||||
/* C token numbers. */
|
||||
enum {
|
||||
CTOK_OFS = 255,
|
||||
#define CTOKNUM(name, sym) CTOK_##name,
|
||||
#define CKWNUM(name) CTOK_##name,
|
||||
CTOKDEF(CTOKNUM)
|
||||
CKWDEF(CKWNUM)
|
||||
#undef CTOKNUM
|
||||
#undef CKWNUM
|
||||
CTOK_FIRSTDECL = CTOK_VOID,
|
||||
CTOK_FIRSTSCL = CTOK_TYPEDEF,
|
||||
CTOK_LASTDECLFLAG = CTOK_REGISTER,
|
||||
CTOK_LASTDECL = CTOK_ENUM
|
||||
};
|
||||
|
||||
/* Declaration specifier flags. */
|
||||
enum {
|
||||
#define CDSFLAG(name) CDF_##name = (1u << (CTOK_##name - CTOK_FIRSTDECL)),
|
||||
CDSDEF(CDSFLAG)
|
||||
#undef CDSFLAG
|
||||
CDF__END
|
||||
};
|
||||
|
||||
#define CDF_SCL (CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC|CDF_AUTO|CDF_REGISTER)
|
||||
|
||||
/* -- C type management --------------------------------------------------- */
|
||||
|
||||
#define ctype_ctsG(g) (mref((g)->ctype_state, CTState))
|
||||
|
||||
/* Get C type state. */
|
||||
static LJ_AINLINE CTState *ctype_cts(lua_State *L)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(G(L));
|
||||
cts->L = L; /* Save L for errors and allocations. */
|
||||
return cts;
|
||||
}
|
||||
|
||||
/* Save and restore state of C type table. */
|
||||
#define LJ_CTYPE_SAVE(cts) CTState savects_ = *(cts)
|
||||
#define LJ_CTYPE_RESTORE(cts) \
|
||||
((cts)->top = savects_.top, \
|
||||
memcpy((cts)->hash, savects_.hash, sizeof(savects_.hash)))
|
||||
|
||||
/* Check C type ID for validity when assertions are enabled. */
|
||||
static LJ_AINLINE CTypeID ctype_check(CTState *cts, CTypeID id)
|
||||
{
|
||||
lua_assert(id > 0 && id < cts->top); UNUSED(cts);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Get C type for C type ID. */
|
||||
static LJ_AINLINE CType *ctype_get(CTState *cts, CTypeID id)
|
||||
{
|
||||
return &cts->tab[ctype_check(cts, id)];
|
||||
}
|
||||
|
||||
/* Get C type ID for a C type. */
|
||||
#define ctype_typeid(cts, ct) ((CTypeID)((ct) - (cts)->tab))
|
||||
|
||||
/* Get child C type. */
|
||||
static LJ_AINLINE CType *ctype_child(CTState *cts, CType *ct)
|
||||
{
|
||||
lua_assert(!(ctype_isvoid(ct->info) || ctype_isstruct(ct->info) ||
|
||||
ctype_isbitfield(ct->info))); /* These don't have children. */
|
||||
return ctype_get(cts, ctype_cid(ct->info));
|
||||
}
|
||||
|
||||
/* Get raw type for a C type ID. */
|
||||
static LJ_AINLINE CType *ctype_raw(CTState *cts, CTypeID id)
|
||||
{
|
||||
CType *ct = ctype_get(cts, id);
|
||||
while (ctype_isattrib(ct->info)) ct = ctype_child(cts, ct);
|
||||
return ct;
|
||||
}
|
||||
|
||||
/* Get raw type of the child of a C type. */
|
||||
static LJ_AINLINE CType *ctype_rawchild(CTState *cts, CType *ct)
|
||||
{
|
||||
do { ct = ctype_child(cts, ct); } while (ctype_isattrib(ct->info));
|
||||
return ct;
|
||||
}
|
||||
|
||||
/* Set the name of a C type table element. */
|
||||
static LJ_AINLINE void ctype_setname(CType *ct, GCstr *s)
|
||||
{
|
||||
/* NOBARRIER: mark string as fixed -- the C type table is never collected. */
|
||||
fixstring(s);
|
||||
setgcref(ct->name, obj2gco(s));
|
||||
}
|
||||
|
||||
LJ_FUNC CTypeID lj_ctype_new(CTState *cts, CType **ctp);
|
||||
LJ_FUNC CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size);
|
||||
LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
|
||||
LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
|
||||
uint32_t tmask);
|
||||
LJ_FUNC CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name,
|
||||
CTSize *ofs, CTInfo *qual);
|
||||
#define lj_ctype_getfield(cts, ct, name, ofs) \
|
||||
lj_ctype_getfieldq((cts), (ct), (name), (ofs), NULL)
|
||||
LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
|
||||
LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
|
||||
LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);
|
||||
LJ_FUNC CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp);
|
||||
LJ_FUNC cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm);
|
||||
LJ_FUNC GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name);
|
||||
LJ_FUNC GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned);
|
||||
LJ_FUNC GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size);
|
||||
LJ_FUNC CTState *lj_ctype_init(lua_State *L);
|
||||
LJ_FUNC void lj_ctype_freestate(global_State *g);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
** Debugging and introspection.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_DEBUG_H
|
||||
#define _LJ_DEBUG_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
typedef struct lj_Debug {
|
||||
/* Common fields. Must be in the same order as in lua.h. */
|
||||
int event;
|
||||
const char *name;
|
||||
const char *namewhat;
|
||||
const char *what;
|
||||
const char *source;
|
||||
int currentline;
|
||||
int nups;
|
||||
int linedefined;
|
||||
int lastlinedefined;
|
||||
char short_src[LUA_IDSIZE];
|
||||
int i_ci;
|
||||
/* Extended fields. Only valid if lj_debug_getinfo() is called with ext = 1.*/
|
||||
int nparams;
|
||||
int isvararg;
|
||||
} lj_Debug;
|
||||
|
||||
LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
|
||||
LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
|
||||
LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx);
|
||||
LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp);
|
||||
LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
|
||||
BCReg slot, const char **name);
|
||||
LJ_FUNC const char *lj_debug_funcname(lua_State *L, cTValue *frame,
|
||||
const char **name);
|
||||
LJ_FUNC void lj_debug_shortname(char *out, GCstr *str, BCLine line);
|
||||
LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
|
||||
cTValue *frame, cTValue *nextframe);
|
||||
LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
|
||||
LJ_FUNC int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar,
|
||||
int ext);
|
||||
#if LJ_HASPROFILE
|
||||
LJ_FUNC void lj_debug_dumpstack(lua_State *L, SBuf *sb, const char *fmt,
|
||||
int depth);
|
||||
#endif
|
||||
|
||||
/* Fixed internal variable names. */
|
||||
#define VARNAMEDEF(_) \
|
||||
_(FOR_IDX, "(for index)") \
|
||||
_(FOR_STOP, "(for limit)") \
|
||||
_(FOR_STEP, "(for step)") \
|
||||
_(FOR_GEN, "(for generator)") \
|
||||
_(FOR_STATE, "(for state)") \
|
||||
_(FOR_CTL, "(for control)")
|
||||
|
||||
enum {
|
||||
VARNAME_END,
|
||||
#define VARNAMEENUM(name, str) VARNAME_##name,
|
||||
VARNAMEDEF(VARNAMEENUM)
|
||||
#undef VARNAMEENUM
|
||||
VARNAME__MAX
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,362 +0,0 @@
|
||||
/*
|
||||
** LuaJIT common internal definitions.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_DEF_H
|
||||
#define _LJ_DEF_H
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
|
||||
//typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#ifdef _WIN64
|
||||
typedef __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else
|
||||
typedef __int32 intptr_t;
|
||||
typedef unsigned __int32 uintptr_t;
|
||||
#endif
|
||||
#elif defined(__symbian__)
|
||||
/* Cough. */
|
||||
typedef signed char int8_t;
|
||||
typedef short int int16_t;
|
||||
typedef int int32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef int intptr_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Needed everywhere. */
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Various VM limits. */
|
||||
#define LJ_MAX_MEM32 0x7fffff00 /* Max. 32 bit memory allocation. */
|
||||
#define LJ_MAX_MEM64 ((uint64_t)1<<47) /* Max. 64 bit memory allocation. */
|
||||
/* Max. total memory allocation. */
|
||||
#define LJ_MAX_MEM (LJ_GC64 ? LJ_MAX_MEM64 : LJ_MAX_MEM32)
|
||||
#define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */
|
||||
#define LJ_MAX_STR LJ_MAX_MEM32 /* Max. string length. */
|
||||
#define LJ_MAX_BUF LJ_MAX_MEM32 /* Max. buffer length. */
|
||||
#define LJ_MAX_UDATA LJ_MAX_MEM32 /* Max. userdata length. */
|
||||
|
||||
#define LJ_MAX_STRTAB (1<<26) /* Max. string table size. */
|
||||
#define LJ_MAX_HBITS 26 /* Max. hash bits. */
|
||||
#define LJ_MAX_ABITS 28 /* Max. bits of array key. */
|
||||
#define LJ_MAX_ASIZE ((1<<(LJ_MAX_ABITS-1))+1) /* Max. array part size. */
|
||||
#define LJ_MAX_COLOSIZE 16 /* Max. elems for colocated array. */
|
||||
|
||||
#define LJ_MAX_LINE LJ_MAX_MEM32 /* Max. source code line number. */
|
||||
#define LJ_MAX_XLEVEL 200 /* Max. syntactic nesting level. */
|
||||
#define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */
|
||||
#define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */
|
||||
#define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */
|
||||
#define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */
|
||||
|
||||
#define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */
|
||||
#define LJ_STACK_EXTRA (5+2*LJ_FR2) /* Extra stack space (metamethods). */
|
||||
|
||||
#define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */
|
||||
|
||||
/* Minimum table/buffer sizes. */
|
||||
#define LJ_MIN_GLOBAL 6 /* Min. global table size (hbits). */
|
||||
#define LJ_MIN_REGISTRY 2 /* Min. registry size (hbits). */
|
||||
#define LJ_MIN_STRTAB 256 /* Min. string table size (pow2). */
|
||||
#define LJ_MIN_SBUF 32 /* Min. string buffer length. */
|
||||
#define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */
|
||||
#define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */
|
||||
#define LJ_MIN_K64SZ 16 /* Min. size for chained K64Array. */
|
||||
|
||||
/* JIT compiler limits. */
|
||||
#define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */
|
||||
#define LJ_MAX_PHI 64 /* Max. # of PHIs for a loop. */
|
||||
#define LJ_MAX_EXITSTUBGR 16 /* Max. # of exit stub groups. */
|
||||
|
||||
/* Various macros. */
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
|
||||
#endif
|
||||
|
||||
#define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo)
|
||||
#define i32ptr(p) ((int32_t)(intptr_t)(void *)(p))
|
||||
#define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p))
|
||||
#define i64ptr(p) ((int64_t)(intptr_t)(void *)(p))
|
||||
#define u64ptr(p) ((uint64_t)(intptr_t)(void *)(p))
|
||||
#define igcptr(p) (LJ_GC64 ? i64ptr(p) : i32ptr(p))
|
||||
|
||||
#define checki8(x) ((x) == (int32_t)(int8_t)(x))
|
||||
#define checku8(x) ((x) == (int32_t)(uint8_t)(x))
|
||||
#define checki16(x) ((x) == (int32_t)(int16_t)(x))
|
||||
#define checku16(x) ((x) == (int32_t)(uint16_t)(x))
|
||||
#define checki32(x) ((x) == (int32_t)(x))
|
||||
#define checku32(x) ((x) == (uint32_t)(x))
|
||||
#define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x))
|
||||
#define checkptr47(x) (((uint64_t)(uintptr_t)(x) >> 47) == 0)
|
||||
#define checkptrGC(x) (LJ_GC64 ? checkptr47((x)) : LJ_64 ? checkptr32((x)) :1)
|
||||
|
||||
/* Every half-decent C compiler transforms this into a rotate instruction. */
|
||||
#define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1))))
|
||||
#define lj_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n)))
|
||||
|
||||
/* A really naive Bloom filter. But sufficient for our needs. */
|
||||
typedef uintptr_t BloomFilter;
|
||||
#define BLOOM_MASK (8*sizeof(BloomFilter) - 1)
|
||||
#define bloombit(x) ((uintptr_t)1 << ((x) & BLOOM_MASK))
|
||||
#define bloomset(b, x) ((b) |= bloombit((x)))
|
||||
#define bloomtest(b, x) ((b) & bloombit((x)))
|
||||
|
||||
#if defined(__GNUC__) || defined(__psp2__)
|
||||
|
||||
#define LJ_NORET __attribute__((noreturn))
|
||||
#define LJ_ALIGN(n) __attribute__((aligned(n)))
|
||||
#define LJ_INLINE inline
|
||||
#define LJ_AINLINE inline __attribute__((always_inline))
|
||||
#define LJ_NOINLINE __attribute__((noinline))
|
||||
|
||||
#if defined(__ELF__) || defined(__MACH__) || defined(__psp2__)
|
||||
#if !((defined(__sun__) && defined(__svr4__)) || defined(__CELLOS_LV2__))
|
||||
#define LJ_NOAPI extern __attribute__((visibility("hidden")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Note: it's only beneficial to use fastcall on x86 and then only for up to
|
||||
** two non-FP args. The amalgamated compile covers all LJ_FUNC cases. Only
|
||||
** indirect calls and related tail-called C functions are marked as fastcall.
|
||||
*/
|
||||
#if defined(__i386__)
|
||||
#define LJ_FASTCALL __attribute__((fastcall))
|
||||
#endif
|
||||
|
||||
#define LJ_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define LJ_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define lj_ffs(x) ((uint32_t)__builtin_ctz(x))
|
||||
/* Don't ask ... */
|
||||
#if defined(__INTEL_COMPILER) && (defined(__i386__) || defined(__x86_64__))
|
||||
static LJ_AINLINE uint32_t lj_fls(uint32_t x)
|
||||
{
|
||||
uint32_t r; __asm__("bsrl %1, %0" : "=r" (r) : "rm" (x) : "cc"); return r;
|
||||
}
|
||||
#else
|
||||
#define lj_fls(x) ((uint32_t)(__builtin_clz(x)^31))
|
||||
#endif
|
||||
|
||||
#if defined(__arm__)
|
||||
static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
|
||||
{
|
||||
#if defined(__psp2__)
|
||||
return __builtin_rev(x);
|
||||
#else
|
||||
uint32_t r;
|
||||
#if __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6T2__ || __ARM_ARCH_6Z__ ||\
|
||||
__ARM_ARCH_6ZK__ || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__
|
||||
__asm__("rev %0, %1" : "=r" (r) : "r" (x));
|
||||
return r;
|
||||
#else
|
||||
#ifdef __thumb__
|
||||
r = x ^ lj_ror(x, 16);
|
||||
#else
|
||||
__asm__("eor %0, %1, %1, ror #16" : "=r" (r) : "r" (x));
|
||||
#endif
|
||||
return ((r & 0xff00ffffu) >> 8) ^ lj_ror(x, 8);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
|
||||
{
|
||||
return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
|
||||
}
|
||||
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||
static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
|
||||
{
|
||||
return (uint32_t)__builtin_bswap32((int32_t)x);
|
||||
}
|
||||
|
||||
static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
|
||||
{
|
||||
return (uint64_t)__builtin_bswap64((int64_t)x);
|
||||
}
|
||||
#elif defined(__i386__) || defined(__x86_64__)
|
||||
static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
|
||||
{
|
||||
uint32_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
|
||||
{
|
||||
return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
|
||||
}
|
||||
#else
|
||||
static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
|
||||
{
|
||||
uint64_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
|
||||
{
|
||||
return (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24);
|
||||
}
|
||||
|
||||
static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
|
||||
{
|
||||
return (uint64_t)lj_bswap((uint32_t)(x >> 32)) |
|
||||
((uint64_t)lj_bswap((uint32_t)x) << 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef union __attribute__((packed)) Unaligned16 {
|
||||
uint16_t u;
|
||||
uint8_t b[2];
|
||||
} Unaligned16;
|
||||
|
||||
typedef union __attribute__((packed)) Unaligned32 {
|
||||
uint32_t u;
|
||||
uint8_t b[4];
|
||||
} Unaligned32;
|
||||
|
||||
/* Unaligned load of uint16_t. */
|
||||
static LJ_AINLINE uint16_t lj_getu16(const void *p)
|
||||
{
|
||||
return ((const Unaligned16 *)p)->u;
|
||||
}
|
||||
|
||||
/* Unaligned load of uint32_t. */
|
||||
static LJ_AINLINE uint32_t lj_getu32(const void *p)
|
||||
{
|
||||
return ((const Unaligned32 *)p)->u;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define LJ_NORET __declspec(noreturn)
|
||||
#define LJ_ALIGN(n) __declspec(align(n))
|
||||
#define LJ_INLINE __inline
|
||||
#define LJ_AINLINE __forceinline
|
||||
#define LJ_NOINLINE __declspec(noinline)
|
||||
#if defined(_M_IX86)
|
||||
#define LJ_FASTCALL __fastcall
|
||||
#endif
|
||||
|
||||
#ifdef _M_PPC
|
||||
unsigned int _CountLeadingZeros(long);
|
||||
#pragma intrinsic(_CountLeadingZeros)
|
||||
static LJ_AINLINE uint32_t lj_fls(uint32_t x)
|
||||
{
|
||||
return _CountLeadingZeros(x) ^ 31;
|
||||
}
|
||||
#else
|
||||
unsigned char _BitScanForward(uint32_t *, unsigned long);
|
||||
unsigned char _BitScanReverse(uint32_t *, unsigned long);
|
||||
#pragma intrinsic(_BitScanForward)
|
||||
#pragma intrinsic(_BitScanReverse)
|
||||
|
||||
static LJ_AINLINE uint32_t lj_ffs(uint32_t x)
|
||||
{
|
||||
uint32_t r; _BitScanForward(&r, x); return r;
|
||||
}
|
||||
|
||||
static LJ_AINLINE uint32_t lj_fls(uint32_t x)
|
||||
{
|
||||
uint32_t r; _BitScanReverse(&r, x); return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long _byteswap_ulong(unsigned long);
|
||||
uint64_t _byteswap_uint64(uint64_t);
|
||||
#define lj_bswap(x) (_byteswap_ulong((x)))
|
||||
#define lj_bswap64(x) (_byteswap_uint64((x)))
|
||||
|
||||
#if defined(_M_PPC) && defined(LUAJIT_NO_UNALIGNED)
|
||||
/*
|
||||
** Replacement for unaligned loads on Xbox 360. Disabled by default since it's
|
||||
** usually more costly than the occasional stall when crossing a cache-line.
|
||||
*/
|
||||
static LJ_AINLINE uint16_t lj_getu16(const void *v)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)v;
|
||||
return (uint16_t)((p[0]<<8) | p[1]);
|
||||
}
|
||||
static LJ_AINLINE uint32_t lj_getu32(const void *v)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)v;
|
||||
return (uint32_t)((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]);
|
||||
}
|
||||
#else
|
||||
/* Unaligned loads are generally ok on x86/x64. */
|
||||
#define lj_getu16(p) (*(uint16_t *)(p))
|
||||
#define lj_getu32(p) (*(uint32_t *)(p))
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "missing defines for your compiler"
|
||||
#endif
|
||||
|
||||
/* Optional defines. */
|
||||
#ifndef LJ_FASTCALL
|
||||
#define LJ_FASTCALL
|
||||
#endif
|
||||
#ifndef LJ_NORET
|
||||
#define LJ_NORET
|
||||
#endif
|
||||
#ifndef LJ_NOAPI
|
||||
#define LJ_NOAPI extern
|
||||
#endif
|
||||
#ifndef LJ_LIKELY
|
||||
#define LJ_LIKELY(x) (x)
|
||||
#define LJ_UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
/* Attributes for internal functions. */
|
||||
#define LJ_DATA LJ_NOAPI
|
||||
#define LJ_DATADEF
|
||||
#define LJ_ASMF LJ_NOAPI
|
||||
#define LJ_FUNCA LJ_NOAPI
|
||||
#if defined(ljamalg_c)
|
||||
#define LJ_FUNC static
|
||||
#else
|
||||
#define LJ_FUNC LJ_NOAPI
|
||||
#endif
|
||||
#define LJ_FUNC_NORET LJ_FUNC LJ_NORET
|
||||
#define LJ_FUNCA_NORET LJ_FUNCA LJ_NORET
|
||||
#define LJ_ASMF_NORET LJ_ASMF LJ_NORET
|
||||
|
||||
/* Runtime assertions. */
|
||||
#ifdef lua_assert
|
||||
#define check_exp(c, e) (lua_assert(c), (e))
|
||||
#define api_check(l, e) lua_assert(e)
|
||||
#else
|
||||
#define lua_assert(c) ((void)0)
|
||||
#define check_exp(c, e) (e)
|
||||
#define api_check luai_apicheck
|
||||
#endif
|
||||
|
||||
/* Static assertions. */
|
||||
#define LJ_ASSERT_NAME2(name, line) name ## line
|
||||
#define LJ_ASSERT_NAME(line) LJ_ASSERT_NAME2(lj_assert_, line)
|
||||
#ifdef __COUNTER__
|
||||
#define LJ_STATIC_ASSERT(cond) \
|
||||
//extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
|
||||
#else
|
||||
#define LJ_STATIC_ASSERT(cond) \
|
||||
extern void LJ_ASSERT_NAME(__LINE__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
** Instruction dispatch handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_DISPATCH_H
|
||||
#define _LJ_DISPATCH_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_bc.h"
|
||||
#if LJ_HASJIT
|
||||
#include "lj_jit.h"
|
||||
#endif
|
||||
|
||||
#if LJ_TARGET_MIPS
|
||||
/* Need our own global offset table for the dreaded MIPS calling conventions. */
|
||||
|
||||
#ifndef _LJ_VM_H
|
||||
LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b);
|
||||
#endif
|
||||
|
||||
#if LJ_SOFTFP
|
||||
#ifndef _LJ_IRCALL_H
|
||||
extern double __adddf3(double a, double b);
|
||||
extern double __subdf3(double a, double b);
|
||||
extern double __muldf3(double a, double b);
|
||||
extern double __divdf3(double a, double b);
|
||||
#endif
|
||||
#define SFGOTDEF(_) _(sqrt) _(__adddf3) _(__subdf3) _(__muldf3) _(__divdf3)
|
||||
#else
|
||||
#define SFGOTDEF(_)
|
||||
#endif
|
||||
#if LJ_HASJIT
|
||||
#define JITGOTDEF(_) _(lj_trace_exit) _(lj_trace_hot)
|
||||
#else
|
||||
#define JITGOTDEF(_)
|
||||
#endif
|
||||
#if LJ_HASFFI
|
||||
#define FFIGOTDEF(_) \
|
||||
_(lj_meta_equal_cd) _(lj_ccallback_enter) _(lj_ccallback_leave)
|
||||
#else
|
||||
#define FFIGOTDEF(_)
|
||||
#endif
|
||||
#define GOTDEF(_) \
|
||||
_(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \
|
||||
_(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \
|
||||
_(pow) _(fmod) _(ldexp) _(lj_vm_modi) \
|
||||
_(lj_dispatch_call) _(lj_dispatch_ins) _(lj_dispatch_stitch) \
|
||||
_(lj_dispatch_profile) _(lj_err_throw) \
|
||||
_(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \
|
||||
_(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
|
||||
_(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
|
||||
_(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \
|
||||
_(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_number) \
|
||||
_(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \
|
||||
_(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
|
||||
_(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \
|
||||
_(lj_buf_putstr_upper) _(lj_buf_tostr) \
|
||||
JITGOTDEF(_) FFIGOTDEF(_) SFGOTDEF(_)
|
||||
|
||||
enum {
|
||||
#define GOTENUM(name) LJ_GOT_##name,
|
||||
GOTDEF(GOTENUM)
|
||||
#undef GOTENUM
|
||||
LJ_GOT__MAX
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Type of hot counter. Must match the code in the assembler VM. */
|
||||
/* 16 bits are sufficient. Only 0.0015% overhead with maximum slot penalty. */
|
||||
typedef uint16_t HotCount;
|
||||
|
||||
/* Number of hot counter hash table entries (must be a power of two). */
|
||||
#define HOTCOUNT_SIZE 64
|
||||
#define HOTCOUNT_PCMASK ((HOTCOUNT_SIZE-1)*sizeof(HotCount))
|
||||
|
||||
/* Hotcount decrements. */
|
||||
#define HOTCOUNT_LOOP 2
|
||||
#define HOTCOUNT_CALL 1
|
||||
|
||||
/* This solves a circular dependency problem -- bump as needed. Sigh. */
|
||||
#define GG_NUM_ASMFF 57
|
||||
|
||||
#define GG_LEN_DDISP (BC__MAX + GG_NUM_ASMFF)
|
||||
#define GG_LEN_SDISP BC_FUNCF
|
||||
#define GG_LEN_DISP (GG_LEN_DDISP + GG_LEN_SDISP)
|
||||
|
||||
/* Global state, main thread and extra fields are allocated together. */
|
||||
typedef struct GG_State {
|
||||
lua_State L; /* Main thread. */
|
||||
global_State g; /* Global state. */
|
||||
#if LJ_TARGET_MIPS
|
||||
ASMFunction got[LJ_GOT__MAX]; /* Global offset table. */
|
||||
#endif
|
||||
#if LJ_HASJIT
|
||||
jit_State J; /* JIT state. */
|
||||
HotCount hotcount[HOTCOUNT_SIZE]; /* Hot counters. */
|
||||
#endif
|
||||
ASMFunction dispatch[GG_LEN_DISP]; /* Instruction dispatch tables. */
|
||||
BCIns bcff[GG_NUM_ASMFF]; /* Bytecode for ASM fast functions. */
|
||||
} GG_State;
|
||||
|
||||
#define GG_OFS(field) ((int)offsetof(GG_State, field))
|
||||
#define G2GG(gl) ((GG_State *)((char *)(gl) - GG_OFS(g)))
|
||||
#define J2GG(j) ((GG_State *)((char *)(j) - GG_OFS(J)))
|
||||
#define L2GG(L) (G2GG(G(L)))
|
||||
#define J2G(J) (&J2GG(J)->g)
|
||||
#define G2J(gl) (&G2GG(gl)->J)
|
||||
#define L2J(L) (&L2GG(L)->J)
|
||||
#define GG_G2J (GG_OFS(J) - GG_OFS(g))
|
||||
#define GG_G2DISP (GG_OFS(dispatch) - GG_OFS(g))
|
||||
#define GG_DISP2G (GG_OFS(g) - GG_OFS(dispatch))
|
||||
#define GG_DISP2J (GG_OFS(J) - GG_OFS(dispatch))
|
||||
#define GG_DISP2HOT (GG_OFS(hotcount) - GG_OFS(dispatch))
|
||||
#define GG_DISP2STATIC (GG_LEN_DDISP*(int)sizeof(ASMFunction))
|
||||
|
||||
#define hotcount_get(gg, pc) \
|
||||
(gg)->hotcount[(u32ptr(pc)>>2) & (HOTCOUNT_SIZE-1)]
|
||||
#define hotcount_set(gg, pc, val) \
|
||||
(hotcount_get((gg), (pc)) = (HotCount)(val))
|
||||
|
||||
/* Dispatch table management. */
|
||||
LJ_FUNC void lj_dispatch_init(GG_State *GG);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC void lj_dispatch_init_hotcount(global_State *g);
|
||||
#endif
|
||||
LJ_FUNC void lj_dispatch_update(global_State *g);
|
||||
|
||||
/* Instruction dispatch callback for hooks or when recording. */
|
||||
LJ_FUNCA void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc);
|
||||
LJ_FUNCA ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns*pc);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNCA void LJ_FASTCALL lj_dispatch_stitch(jit_State *J, const BCIns *pc);
|
||||
#endif
|
||||
#if LJ_HASPROFILE
|
||||
LJ_FUNCA void LJ_FASTCALL lj_dispatch_profile(lua_State *L, const BCIns *pc);
|
||||
#endif
|
||||
|
||||
#if LJ_HASFFI && !defined(_BUILDVM_H)
|
||||
/* Save/restore errno and GetLastError() around hooks, exits and recording. */
|
||||
#include <errno.h>
|
||||
#if LJ_TARGET_WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#define ERRNO_SAVE int olderr = errno; DWORD oldwerr = GetLastError();
|
||||
#define ERRNO_RESTORE errno = olderr; SetLastError(oldwerr);
|
||||
#else
|
||||
#define ERRNO_SAVE int olderr = errno;
|
||||
#define ERRNO_RESTORE errno = olderr;
|
||||
#endif
|
||||
#else
|
||||
#define ERRNO_SAVE
|
||||
#define ERRNO_RESTORE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
** ARM instruction emitter.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Constant encoding --------------------------------------------------- */
|
||||
|
||||
static uint8_t emit_invai[16] = {
|
||||
/* AND */ (ARMI_AND^ARMI_BIC) >> 21,
|
||||
/* EOR */ 0,
|
||||
/* SUB */ (ARMI_SUB^ARMI_ADD) >> 21,
|
||||
/* RSB */ 0,
|
||||
/* ADD */ (ARMI_ADD^ARMI_SUB) >> 21,
|
||||
/* ADC */ (ARMI_ADC^ARMI_SBC) >> 21,
|
||||
/* SBC */ (ARMI_SBC^ARMI_ADC) >> 21,
|
||||
/* RSC */ 0,
|
||||
/* TST */ 0,
|
||||
/* TEQ */ 0,
|
||||
/* CMP */ (ARMI_CMP^ARMI_CMN) >> 21,
|
||||
/* CMN */ (ARMI_CMN^ARMI_CMP) >> 21,
|
||||
/* ORR */ 0,
|
||||
/* MOV */ (ARMI_MOV^ARMI_MVN) >> 21,
|
||||
/* BIC */ (ARMI_BIC^ARMI_AND) >> 21,
|
||||
/* MVN */ (ARMI_MVN^ARMI_MOV) >> 21
|
||||
};
|
||||
|
||||
/* Encode constant in K12 format for data processing instructions. */
|
||||
static uint32_t emit_isk12(ARMIns ai, int32_t n)
|
||||
{
|
||||
uint32_t invai, i, m = (uint32_t)n;
|
||||
/* K12: unsigned 8 bit value, rotated in steps of two bits. */
|
||||
for (i = 0; i < 4096; i += 256, m = lj_rol(m, 2))
|
||||
if (m <= 255) return ARMI_K12|m|i;
|
||||
/* Otherwise try negation/complement with the inverse instruction. */
|
||||
invai = emit_invai[((ai >> 21) & 15)];
|
||||
if (!invai) return 0; /* Failed. No inverse instruction. */
|
||||
m = ~(uint32_t)n;
|
||||
if (invai == ((ARMI_SUB^ARMI_ADD) >> 21) ||
|
||||
invai == (ARMI_CMP^ARMI_CMN) >> 21) m++;
|
||||
for (i = 0; i < 4096; i += 256, m = lj_rol(m, 2))
|
||||
if (m <= 255) return ARMI_K12|(invai<<21)|m|i;
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
||||
/* -- Emit basic instructions --------------------------------------------- */
|
||||
|
||||
static void emit_dnm(ASMState *as, ARMIns ai, Reg rd, Reg rn, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_D(rd) | ARMF_N(rn) | ARMF_M(rm);
|
||||
}
|
||||
|
||||
static void emit_dm(ASMState *as, ARMIns ai, Reg rd, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_D(rd) | ARMF_M(rm);
|
||||
}
|
||||
|
||||
static void emit_dn(ASMState *as, ARMIns ai, Reg rd, Reg rn)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_D(rd) | ARMF_N(rn);
|
||||
}
|
||||
|
||||
static void emit_nm(ASMState *as, ARMIns ai, Reg rn, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_N(rn) | ARMF_M(rm);
|
||||
}
|
||||
|
||||
static void emit_d(ASMState *as, ARMIns ai, Reg rd)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_D(rd);
|
||||
}
|
||||
|
||||
static void emit_n(ASMState *as, ARMIns ai, Reg rn)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_N(rn);
|
||||
}
|
||||
|
||||
static void emit_m(ASMState *as, ARMIns ai, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | ARMF_M(rm);
|
||||
}
|
||||
|
||||
static void emit_lsox(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
|
||||
{
|
||||
lua_assert(ofs >= -255 && ofs <= 255);
|
||||
if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
|
||||
*--as->mcp = ai | ARMI_LS_P | ARMI_LSX_I | ARMF_D(rd) | ARMF_N(rn) |
|
||||
((ofs & 0xf0) << 4) | (ofs & 0x0f);
|
||||
}
|
||||
|
||||
static void emit_lso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
|
||||
{
|
||||
lua_assert(ofs >= -4095 && ofs <= 4095);
|
||||
/* Combine LDR/STR pairs to LDRD/STRD. */
|
||||
if (*as->mcp == (ai|ARMI_LS_P|ARMI_LS_U|ARMF_D(rd^1)|ARMF_N(rn)|(ofs^4)) &&
|
||||
(ai & ~(ARMI_LDR^ARMI_STR)) == ARMI_STR && rd != rn &&
|
||||
(uint32_t)ofs <= 252 && !(ofs & 3) && !((rd ^ (ofs >>2)) & 1) &&
|
||||
as->mcp != as->mcloop) {
|
||||
as->mcp++;
|
||||
emit_lsox(as, ai == ARMI_LDR ? ARMI_LDRD : ARMI_STRD, rd&~1, rn, ofs&~4);
|
||||
return;
|
||||
}
|
||||
if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
|
||||
*--as->mcp = ai | ARMI_LS_P | ARMF_D(rd) | ARMF_N(rn) | ofs;
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
static void emit_vlso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
|
||||
{
|
||||
lua_assert(ofs >= -1020 && ofs <= 1020 && (ofs&3) == 0);
|
||||
if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
|
||||
*--as->mcp = ai | ARMI_LS_P | ARMF_D(rd & 15) | ARMF_N(rn) | (ofs >> 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- Emit loads/stores --------------------------------------------------- */
|
||||
|
||||
/* Prefer spills of BASE/L. */
|
||||
#define emit_canremat(ref) ((ref) < ASMREF_L)
|
||||
|
||||
/* Try to find a one step delta relative to another constant. */
|
||||
static int emit_kdelta1(ASMState *as, Reg d, int32_t i)
|
||||
{
|
||||
RegSet work = ~as->freeset & RSET_GPR;
|
||||
while (work) {
|
||||
Reg r = rset_picktop(work);
|
||||
IRRef ref = regcost_ref(as->cost[r]);
|
||||
lua_assert(r != d);
|
||||
if (emit_canremat(ref)) {
|
||||
int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
|
||||
uint32_t k = emit_isk12(ARMI_ADD, delta);
|
||||
if (k) {
|
||||
if (k == ARMI_K12)
|
||||
emit_dm(as, ARMI_MOV, d, r);
|
||||
else
|
||||
emit_dn(as, ARMI_ADD^k, d, r);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
rset_clear(work, r);
|
||||
}
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
||||
/* Try to find a two step delta relative to another constant. */
|
||||
static int emit_kdelta2(ASMState *as, Reg d, int32_t i)
|
||||
{
|
||||
RegSet work = ~as->freeset & RSET_GPR;
|
||||
while (work) {
|
||||
Reg r = rset_picktop(work);
|
||||
IRRef ref = regcost_ref(as->cost[r]);
|
||||
lua_assert(r != d);
|
||||
if (emit_canremat(ref)) {
|
||||
int32_t other = ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i;
|
||||
if (other) {
|
||||
int32_t delta = i - other;
|
||||
uint32_t sh, inv = 0, k2, k;
|
||||
if (delta < 0) { delta = -delta; inv = ARMI_ADD^ARMI_SUB; }
|
||||
sh = lj_ffs(delta) & ~1;
|
||||
k2 = emit_isk12(0, delta & (255 << sh));
|
||||
k = emit_isk12(0, delta & ~(255 << sh));
|
||||
if (k) {
|
||||
emit_dn(as, ARMI_ADD^k2^inv, d, d);
|
||||
emit_dn(as, ARMI_ADD^k^inv, d, r);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
rset_clear(work, r);
|
||||
}
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
||||
/* Load a 32 bit constant into a GPR. */
|
||||
static void emit_loadi(ASMState *as, Reg r, int32_t i)
|
||||
{
|
||||
uint32_t k = emit_isk12(ARMI_MOV, i);
|
||||
lua_assert(rset_test(as->freeset, r) || r == RID_TMP);
|
||||
if (k) {
|
||||
/* Standard K12 constant. */
|
||||
emit_d(as, ARMI_MOV^k, r);
|
||||
} else if ((as->flags & JIT_F_ARMV6T2) && (uint32_t)i < 0x00010000u) {
|
||||
/* 16 bit loword constant for ARMv6T2. */
|
||||
emit_d(as, ARMI_MOVW|(i & 0x0fff)|((i & 0xf000)<<4), r);
|
||||
} else if (emit_kdelta1(as, r, i)) {
|
||||
/* One step delta relative to another constant. */
|
||||
} else if ((as->flags & JIT_F_ARMV6T2)) {
|
||||
/* 32 bit hiword/loword constant for ARMv6T2. */
|
||||
emit_d(as, ARMI_MOVT|((i>>16) & 0x0fff)|(((i>>16) & 0xf000)<<4), r);
|
||||
emit_d(as, ARMI_MOVW|(i & 0x0fff)|((i & 0xf000)<<4), r);
|
||||
} else if (emit_kdelta2(as, r, i)) {
|
||||
/* Two step delta relative to another constant. */
|
||||
} else {
|
||||
/* Otherwise construct the constant with up to 4 instructions. */
|
||||
/* NYI: use mvn+bic, use pc-relative loads. */
|
||||
for (;;) {
|
||||
uint32_t sh = lj_ffs(i) & ~1;
|
||||
int32_t m = i & (255 << sh);
|
||||
i &= ~(255 << sh);
|
||||
if (i == 0) {
|
||||
emit_d(as, ARMI_MOV ^ emit_isk12(0, m), r);
|
||||
break;
|
||||
}
|
||||
emit_dn(as, ARMI_ORR ^ emit_isk12(0, m), r, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
|
||||
|
||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
|
||||
|
||||
/* Get/set from constant pointer. */
|
||||
static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p)
|
||||
{
|
||||
int32_t i = i32ptr(p);
|
||||
emit_lso(as, ai, r, ra_allock(as, (i & ~4095), rset_exclude(RSET_GPR, r)),
|
||||
(i & 4095));
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
/* Load a number constant into an FPR. */
|
||||
static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||
{
|
||||
cTValue *tv = ir_knum(ir);
|
||||
int32_t i;
|
||||
if ((as->flags & JIT_F_VFPV3) && !tv->u32.lo) {
|
||||
uint32_t hi = tv->u32.hi;
|
||||
uint32_t b = ((hi >> 22) & 0x1ff);
|
||||
if (!(hi & 0xffff) && (b == 0x100 || b == 0x0ff)) {
|
||||
*--as->mcp = ARMI_VMOVI_D | ARMF_D(r & 15) |
|
||||
((tv->u32.hi >> 12) & 0x00080000) |
|
||||
((tv->u32.hi >> 4) & 0x00070000) |
|
||||
((tv->u32.hi >> 16) & 0x0000000f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
i = i32ptr(tv);
|
||||
emit_vlso(as, ARMI_VLDR_D, r,
|
||||
ra_allock(as, (i & ~1020), RSET_GPR), (i & 1020));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get/set global_State fields. */
|
||||
#define emit_getgl(as, r, field) \
|
||||
emit_lsptr(as, ARMI_LDR, (r), (void *)&J2G(as->J)->field)
|
||||
#define emit_setgl(as, r, field) \
|
||||
emit_lsptr(as, ARMI_STR, (r), (void *)&J2G(as->J)->field)
|
||||
|
||||
/* Trace number is determined from pc of exit instruction. */
|
||||
#define emit_setvmstate(as, i) UNUSED(i)
|
||||
|
||||
/* -- Emit control-flow instructions -------------------------------------- */
|
||||
|
||||
/* Label for internal jumps. */
|
||||
typedef MCode *MCLabel;
|
||||
|
||||
/* Return label pointing to current PC. */
|
||||
#define emit_label(as) ((as)->mcp)
|
||||
|
||||
static void emit_branch(ASMState *as, ARMIns ai, MCode *target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
ptrdiff_t delta = (target - p) - 1;
|
||||
lua_assert(((delta + 0x00800000) >> 24) == 0);
|
||||
*--p = ai | ((uint32_t)delta & 0x00ffffffu);
|
||||
as->mcp = p;
|
||||
}
|
||||
|
||||
#define emit_jmp(as, target) emit_branch(as, ARMI_B, (target))
|
||||
|
||||
static void emit_call(ASMState *as, void *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = ((char *)target - (char *)p) - 8;
|
||||
if ((((delta>>2) + 0x00800000) >> 24) == 0) {
|
||||
if ((delta & 1))
|
||||
*p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 23);
|
||||
else
|
||||
*p = ARMI_BL | ((uint32_t)(delta>>2) & 0x00ffffffu);
|
||||
} else { /* Target out of range: need indirect call. But don't use R0-R3. */
|
||||
Reg r = ra_allock(as, i32ptr(target), RSET_RANGE(RID_R4, RID_R12+1));
|
||||
*p = ARMI_BLXr | ARMF_M(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Emit generic operations --------------------------------------------- */
|
||||
|
||||
/* Generic move between two regs. */
|
||||
static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
|
||||
{
|
||||
#if LJ_SOFTFP
|
||||
lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
|
||||
#else
|
||||
if (dst >= RID_MAX_GPR) {
|
||||
emit_dm(as, irt_isnum(ir->t) ? ARMI_VMOV_D : ARMI_VMOV_S,
|
||||
(dst & 15), (src & 15));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (as->mcp != as->mcloop) { /* Swap early registers for loads/stores. */
|
||||
MCode ins = *as->mcp, swp = (src^dst);
|
||||
if ((ins & 0x0c000000) == 0x04000000 && (ins & 0x02000010) != 0x02000010) {
|
||||
if (!((ins ^ (dst << 16)) & 0x000f0000))
|
||||
*as->mcp = ins ^ (swp << 16); /* Swap N in load/store. */
|
||||
if (!(ins & 0x00100000) && !((ins ^ (dst << 12)) & 0x0000f000))
|
||||
*as->mcp = ins ^ (swp << 12); /* Swap D in store. */
|
||||
}
|
||||
}
|
||||
emit_dm(as, ARMI_MOV, dst, src);
|
||||
}
|
||||
|
||||
/* Generic load of register with base and (small) offset address. */
|
||||
static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
#if LJ_SOFTFP
|
||||
lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
|
||||
#else
|
||||
if (r >= RID_MAX_GPR)
|
||||
emit_vlso(as, irt_isnum(ir->t) ? ARMI_VLDR_D : ARMI_VLDR_S, r, base, ofs);
|
||||
else
|
||||
#endif
|
||||
emit_lso(as, ARMI_LDR, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Generic store of register with base and (small) offset address. */
|
||||
static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
#if LJ_SOFTFP
|
||||
lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
|
||||
#else
|
||||
if (r >= RID_MAX_GPR)
|
||||
emit_vlso(as, irt_isnum(ir->t) ? ARMI_VSTR_D : ARMI_VSTR_S, r, base, ofs);
|
||||
else
|
||||
#endif
|
||||
emit_lso(as, ARMI_STR, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Emit an arithmetic/logic operation with a constant operand. */
|
||||
static void emit_opk(ASMState *as, ARMIns ai, Reg dest, Reg src,
|
||||
int32_t i, RegSet allow)
|
||||
{
|
||||
uint32_t k = emit_isk12(ai, i);
|
||||
if (k)
|
||||
emit_dn(as, ai^k, dest, src);
|
||||
else
|
||||
emit_dnm(as, ai, dest, src, ra_allock(as, i, allow));
|
||||
}
|
||||
|
||||
/* Add offset to pointer. */
|
||||
static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
|
||||
{
|
||||
if (ofs)
|
||||
emit_opk(as, ARMI_ADD, r, r, ofs, rset_exclude(RSET_GPR, r));
|
||||
}
|
||||
|
||||
#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
|
||||
|
||||
@@ -1,419 +0,0 @@
|
||||
/*
|
||||
** ARM64 instruction emitter.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
|
||||
** Sponsored by Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
/* -- Constant encoding --------------------------------------------------- */
|
||||
|
||||
static uint64_t get_k64val(IRIns *ir)
|
||||
{
|
||||
if (ir->o == IR_KINT64) {
|
||||
return ir_kint64(ir)->u64;
|
||||
} else if (ir->o == IR_KGC) {
|
||||
return (uint64_t)ir_kgc(ir);
|
||||
} else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {
|
||||
return (uint64_t)ir_kptr(ir);
|
||||
} else {
|
||||
lua_assert(ir->o == IR_KINT || ir->o == IR_KNULL);
|
||||
return ir->i; /* Sign-extended. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Encode constant in K12 format for data processing instructions. */
|
||||
static uint32_t emit_isk12(int64_t n)
|
||||
{
|
||||
uint64_t k = (n < 0) ? -n : n;
|
||||
uint32_t m = (n < 0) ? 0x40000000 : 0;
|
||||
if (k < 0x1000) {
|
||||
return A64I_K12|m|A64F_U12(k);
|
||||
} else if ((k & 0xfff000) == k) {
|
||||
return A64I_K12|m|0x400000|A64F_U12(k>>12);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define emit_clz64(n) __builtin_clzll(n)
|
||||
#define emit_ctz64(n) __builtin_ctzll(n)
|
||||
|
||||
/* Encode constant in K13 format for logical data processing instructions. */
|
||||
static uint32_t emit_isk13(uint64_t n, int is64)
|
||||
{
|
||||
int inv = 0, w = 128, lz, tz;
|
||||
if (n & 1) { n = ~n; w = 64; inv = 1; } /* Avoid wrap-around of ones. */
|
||||
if (!n) return 0; /* Neither all-zero nor all-ones are allowed. */
|
||||
do { /* Find the repeat width. */
|
||||
if (is64 && (uint32_t)(n^(n>>32))) break;
|
||||
n = (uint32_t)n;
|
||||
if (!n) return 0; /* Ditto when passing n=0xffffffff and is64=0. */
|
||||
w = 32; if ((n^(n>>16)) & 0xffff) break;
|
||||
n = n & 0xffff; w = 16; if ((n^(n>>8)) & 0xff) break;
|
||||
n = n & 0xff; w = 8; if ((n^(n>>4)) & 0xf) break;
|
||||
n = n & 0xf; w = 4; if ((n^(n>>2)) & 0x3) break;
|
||||
n = n & 0x3; w = 2;
|
||||
} while (0);
|
||||
lz = emit_clz64(n);
|
||||
tz = emit_ctz64(n);
|
||||
if ((int64_t)(n << lz) >> (lz+tz) != -1ll) return 0; /* Non-contiguous? */
|
||||
if (inv)
|
||||
return A64I_K13 | (((lz-w) & 127) << 16) | (((lz+tz-w-1) & 63) << 10);
|
||||
else
|
||||
return A64I_K13 | ((w-tz) << 16) | (((63-lz-tz-w-w) & 63) << 10);
|
||||
}
|
||||
|
||||
static uint32_t emit_isfpk64(uint64_t n)
|
||||
{
|
||||
uint64_t etop9 = ((n >> 54) & 0x1ff);
|
||||
if ((n << 16) == 0 && (etop9 == 0x100 || etop9 == 0x0ff)) {
|
||||
return (uint32_t)(((n >> 48) & 0x7f) | ((n >> 56) & 0x80));
|
||||
}
|
||||
return ~0u;
|
||||
}
|
||||
|
||||
/* -- Emit basic instructions --------------------------------------------- */
|
||||
|
||||
static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra)
|
||||
{
|
||||
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn) | A64F_M(rm) | A64F_A(ra);
|
||||
}
|
||||
|
||||
static void emit_dnm(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn) | A64F_M(rm);
|
||||
}
|
||||
|
||||
static void emit_dm(ASMState *as, A64Ins ai, Reg rd, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | A64F_D(rd) | A64F_M(rm);
|
||||
}
|
||||
|
||||
static void emit_dn(ASMState *as, A64Ins ai, Reg rd, Reg rn)
|
||||
{
|
||||
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn);
|
||||
}
|
||||
|
||||
static void emit_nm(ASMState *as, A64Ins ai, Reg rn, Reg rm)
|
||||
{
|
||||
*--as->mcp = ai | A64F_N(rn) | A64F_M(rm);
|
||||
}
|
||||
|
||||
static void emit_d(ASMState *as, A64Ins ai, Reg rd)
|
||||
{
|
||||
*--as->mcp = ai | A64F_D(rd);
|
||||
}
|
||||
|
||||
static void emit_n(ASMState *as, A64Ins ai, Reg rn)
|
||||
{
|
||||
*--as->mcp = ai | A64F_N(rn);
|
||||
}
|
||||
|
||||
static int emit_checkofs(A64Ins ai, int64_t ofs)
|
||||
{
|
||||
int scale = (ai >> 30) & 3;
|
||||
if (ofs < 0 || (ofs & ((1<<scale)-1))) {
|
||||
return (ofs >= -256 && ofs <= 255) ? -1 : 0;
|
||||
} else {
|
||||
return (ofs < (4096<<scale)) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs)
|
||||
{
|
||||
int ot = emit_checkofs(ai, ofs), sc = (ai >> 30) & 3;
|
||||
lua_assert(ot);
|
||||
/* Combine LDR/STR pairs to LDP/STP. */
|
||||
if ((sc == 2 || sc == 3) &&
|
||||
(!(ai & 0x400000) || rd != rn) &&
|
||||
as->mcp != as->mcloop) {
|
||||
uint32_t prev = *as->mcp & ~A64F_D(31);
|
||||
int ofsm = ofs - (1<<sc), ofsp = ofs + (1<<sc);
|
||||
A64Ins aip;
|
||||
if (prev == (ai | A64F_N(rn) | A64F_U12(ofsm>>sc)) ||
|
||||
prev == ((ai^A64I_LS_U) | A64F_N(rn) | A64F_S9(ofsm&0x1ff))) {
|
||||
aip = (A64F_A(rd) | A64F_D(*as->mcp & 31));
|
||||
} else if (prev == (ai | A64F_N(rn) | A64F_U12(ofsp>>sc)) ||
|
||||
prev == ((ai^A64I_LS_U) | A64F_N(rn) | A64F_S9(ofsp&0x1ff))) {
|
||||
aip = (A64F_D(rd) | A64F_A(*as->mcp & 31));
|
||||
ofsm = ofs;
|
||||
} else {
|
||||
goto nopair;
|
||||
}
|
||||
if (ofsm >= (int)((unsigned int)-64<<sc) && ofsm <= (63<<sc)) {
|
||||
*as->mcp = aip | A64F_N(rn) | ((ofsm >> sc) << 15) |
|
||||
(ai ^ ((ai == A64I_LDRx || ai == A64I_STRx) ? 0x50000000 : 0x90000000));
|
||||
return;
|
||||
}
|
||||
}
|
||||
nopair:
|
||||
if (ot == 1)
|
||||
*--as->mcp = ai | A64F_D(rd) | A64F_N(rn) | A64F_U12(ofs >> sc);
|
||||
else
|
||||
*--as->mcp = (ai^A64I_LS_U) | A64F_D(rd) | A64F_N(rn) | A64F_S9(ofs & 0x1ff);
|
||||
}
|
||||
|
||||
/* -- Emit loads/stores --------------------------------------------------- */
|
||||
|
||||
/* Prefer rematerialization of BASE/L from global_State over spills. */
|
||||
#define emit_canremat(ref) ((ref) <= ASMREF_L)
|
||||
|
||||
/* Try to find an N-step delta relative to other consts with N < lim. */
|
||||
static int emit_kdelta(ASMState *as, Reg rd, uint64_t k, int lim)
|
||||
{
|
||||
RegSet work = ~as->freeset & RSET_GPR;
|
||||
if (lim <= 1) return 0; /* Can't beat that. */
|
||||
while (work) {
|
||||
Reg r = rset_picktop(work);
|
||||
IRRef ref = regcost_ref(as->cost[r]);
|
||||
lua_assert(r != rd);
|
||||
if (ref < REF_TRUE) {
|
||||
uint64_t kx = ra_iskref(ref) ? (uint64_t)ra_krefk(as, ref) :
|
||||
get_k64val(IR(ref));
|
||||
int64_t delta = (int64_t)(k - kx);
|
||||
if (delta == 0) {
|
||||
emit_dm(as, A64I_MOVx, rd, r);
|
||||
return 1;
|
||||
} else {
|
||||
uint32_t k12 = emit_isk12(delta < 0 ? -delta : delta);
|
||||
if (k12) {
|
||||
emit_dn(as, (delta < 0 ? A64I_SUBx : A64I_ADDx)^k12, rd, r);
|
||||
return 1;
|
||||
}
|
||||
/* Do other ops or multi-step deltas pay off? Probably not.
|
||||
** E.g. XOR rarely helps with pointer consts.
|
||||
*/
|
||||
}
|
||||
}
|
||||
rset_clear(work, r);
|
||||
}
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
||||
static void emit_loadk(ASMState *as, Reg rd, uint64_t u64, int is64)
|
||||
{
|
||||
uint32_t k13 = emit_isk13(u64, is64);
|
||||
if (k13) { /* Can the constant be represented as a bitmask immediate? */
|
||||
emit_dn(as, (is64|A64I_ORRw)^k13, rd, RID_ZERO);
|
||||
} else {
|
||||
int i, zeros = 0, ones = 0, neg;
|
||||
if (!is64) u64 = (int64_t)(int32_t)u64; /* Sign-extend. */
|
||||
/* Count homogeneous 16 bit fragments. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
uint64_t frag = (u64 >> i*16) & 0xffff;
|
||||
zeros += (frag == 0);
|
||||
ones += (frag == 0xffff);
|
||||
}
|
||||
neg = ones > zeros; /* Use MOVN if it pays off. */
|
||||
if (!emit_kdelta(as, rd, u64, 4 - (neg ? ones : zeros))) {
|
||||
int shift = 0, lshift = 0;
|
||||
uint64_t n64 = neg ? ~u64 : u64;
|
||||
if (n64 != 0) {
|
||||
/* Find first/last fragment to be filled. */
|
||||
shift = (63-emit_clz64(n64)) & ~15;
|
||||
lshift = emit_ctz64(n64) & ~15;
|
||||
}
|
||||
/* MOVK requires the original value (u64). */
|
||||
while (shift > lshift) {
|
||||
uint32_t u16 = (u64 >> shift) & 0xffff;
|
||||
/* Skip fragments that are correctly filled by MOVN/MOVZ. */
|
||||
if (u16 != (neg ? 0xffff : 0))
|
||||
emit_d(as, is64 | A64I_MOVKw | A64F_U16(u16) | A64F_LSL16(shift), rd);
|
||||
shift -= 16;
|
||||
}
|
||||
/* But MOVN needs an inverted value (n64). */
|
||||
emit_d(as, (neg ? A64I_MOVNx : A64I_MOVZx) |
|
||||
A64F_U16((n64 >> lshift) & 0xffff) | A64F_LSL16(lshift), rd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load a 32 bit constant into a GPR. */
|
||||
#define emit_loadi(as, rd, i) emit_loadk(as, rd, i, 0)
|
||||
|
||||
/* Load a 64 bit constant into a GPR. */
|
||||
#define emit_loadu64(as, rd, i) emit_loadk(as, rd, i, A64I_X)
|
||||
|
||||
#define emit_loada(as, r, addr) emit_loadu64(as, (r), (uintptr_t)(addr))
|
||||
|
||||
#define glofs(as, k) \
|
||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)&J2GG(as->J)->g))
|
||||
#define mcpofs(as, k) \
|
||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)(as->mcp - 1)))
|
||||
#define checkmcpofs(as, k) \
|
||||
((((mcpofs(as, k)>>2) + 0x00040000) >> 19) == 0)
|
||||
|
||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
|
||||
|
||||
/* Get/set from constant pointer. */
|
||||
static void emit_lsptr(ASMState *as, A64Ins ai, Reg r, void *p)
|
||||
{
|
||||
/* First, check if ip + offset is in range. */
|
||||
if ((ai & 0x00400000) && checkmcpofs(as, p)) {
|
||||
emit_d(as, A64I_LDRLx | A64F_S19(mcpofs(as, p)>>2), r);
|
||||
} else {
|
||||
Reg base = RID_GL; /* Next, try GL + offset. */
|
||||
int64_t ofs = glofs(as, p);
|
||||
if (!emit_checkofs(ai, ofs)) { /* Else split up into base reg + offset. */
|
||||
int64_t i64 = i64ptr(p);
|
||||
base = ra_allock(as, (i64 & ~0x7fffull), rset_exclude(RSET_GPR, r));
|
||||
ofs = i64 & 0x7fffull;
|
||||
}
|
||||
emit_lso(as, ai, r, base, ofs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load 64 bit IR constant into register. */
|
||||
static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||
{
|
||||
const uint64_t *k = &ir_k64(ir)->u64;
|
||||
int64_t ofs;
|
||||
if (r >= RID_MAX_GPR) {
|
||||
uint32_t fpk = emit_isfpk64(*k);
|
||||
if (fpk != ~0u) {
|
||||
emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31));
|
||||
return;
|
||||
}
|
||||
}
|
||||
ofs = glofs(as, k);
|
||||
if (emit_checkofs(A64I_LDRx, ofs)) {
|
||||
emit_lso(as, r >= RID_MAX_GPR ? A64I_LDRd : A64I_LDRx,
|
||||
(r & 31), RID_GL, ofs);
|
||||
} else {
|
||||
if (r >= RID_MAX_GPR) {
|
||||
emit_dn(as, A64I_FMOV_D_R, (r & 31), RID_TMP);
|
||||
r = RID_TMP;
|
||||
}
|
||||
if (checkmcpofs(as, k))
|
||||
emit_d(as, A64I_LDRLx | A64F_S19(mcpofs(as, k)>>2), r);
|
||||
else
|
||||
emit_loadu64(as, r, *k);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get/set global_State fields. */
|
||||
#define emit_getgl(as, r, field) \
|
||||
emit_lsptr(as, A64I_LDRx, (r), (void *)&J2G(as->J)->field)
|
||||
#define emit_setgl(as, r, field) \
|
||||
emit_lsptr(as, A64I_STRx, (r), (void *)&J2G(as->J)->field)
|
||||
|
||||
/* Trace number is determined from pc of exit instruction. */
|
||||
#define emit_setvmstate(as, i) UNUSED(i)
|
||||
|
||||
/* -- Emit control-flow instructions -------------------------------------- */
|
||||
|
||||
/* Label for internal jumps. */
|
||||
typedef MCode *MCLabel;
|
||||
|
||||
/* Return label pointing to current PC. */
|
||||
#define emit_label(as) ((as)->mcp)
|
||||
|
||||
static void emit_cond_branch(ASMState *as, A64CC cond, MCode *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(((delta + 0x40000) >> 19) == 0);
|
||||
*p = A64I_BCC | A64F_S19(delta) | cond;
|
||||
}
|
||||
|
||||
static void emit_branch(ASMState *as, A64Ins ai, MCode *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(((delta + 0x02000000) >> 26) == 0);
|
||||
*p = ai | ((uint32_t)delta & 0x03ffffffu);
|
||||
}
|
||||
|
||||
static void emit_tnb(ASMState *as, A64Ins ai, Reg r, uint32_t bit, MCode *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(bit < 63 && ((delta + 0x2000) >> 14) == 0);
|
||||
if (bit > 31) ai |= A64I_X;
|
||||
*p = ai | A64F_BIT(bit & 31) | A64F_S14((uint32_t)delta & 0x3fffu) | r;
|
||||
}
|
||||
|
||||
static void emit_cnb(ASMState *as, A64Ins ai, Reg r, MCode *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(((delta + 0x40000) >> 19) == 0);
|
||||
*p = ai | A64F_S19(delta) | r;
|
||||
}
|
||||
|
||||
#define emit_jmp(as, target) emit_branch(as, A64I_B, (target))
|
||||
|
||||
static void emit_call(ASMState *as, void *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = (char *)target - (char *)p;
|
||||
if ((((delta>>2) + 0x02000000) >> 26) == 0) {
|
||||
*p = A64I_BL | ((uint32_t)(delta>>2) & 0x03ffffffu);
|
||||
} else { /* Target out of range: need indirect call. But don't use R0-R7. */
|
||||
Reg r = ra_allock(as, i64ptr(target),
|
||||
RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED);
|
||||
*p = A64I_BLR | A64F_N(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Emit generic operations --------------------------------------------- */
|
||||
|
||||
/* Generic move between two regs. */
|
||||
static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
|
||||
{
|
||||
if (dst >= RID_MAX_GPR) {
|
||||
emit_dn(as, irt_isnum(ir->t) ? A64I_FMOV_D : A64I_FMOV_S,
|
||||
(dst & 31), (src & 31));
|
||||
return;
|
||||
}
|
||||
if (as->mcp != as->mcloop) { /* Swap early registers for loads/stores. */
|
||||
MCode ins = *as->mcp, swp = (src^dst);
|
||||
if ((ins & 0xbf800000) == 0xb9000000) {
|
||||
if (!((ins ^ (dst << 5)) & 0x000003e0))
|
||||
*as->mcp = ins ^ (swp << 5); /* Swap N in load/store. */
|
||||
if (!(ins & 0x00400000) && !((ins ^ dst) & 0x0000001f))
|
||||
*as->mcp = ins ^ swp; /* Swap D in store. */
|
||||
}
|
||||
}
|
||||
emit_dm(as, A64I_MOVx, dst, src);
|
||||
}
|
||||
|
||||
/* Generic load of register with base and (small) offset address. */
|
||||
static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r >= RID_MAX_GPR)
|
||||
emit_lso(as, irt_isnum(ir->t) ? A64I_LDRd : A64I_LDRs, (r & 31), base, ofs);
|
||||
else
|
||||
emit_lso(as, irt_is64(ir->t) ? A64I_LDRx : A64I_LDRw, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Generic store of register with base and (small) offset address. */
|
||||
static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r >= RID_MAX_GPR)
|
||||
emit_lso(as, irt_isnum(ir->t) ? A64I_STRd : A64I_STRs, (r & 31), base, ofs);
|
||||
else
|
||||
emit_lso(as, irt_is64(ir->t) ? A64I_STRx : A64I_STRw, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Emit an arithmetic operation with a constant operand. */
|
||||
static void emit_opk(ASMState *as, A64Ins ai, Reg dest, Reg src,
|
||||
int32_t i, RegSet allow)
|
||||
{
|
||||
uint32_t k = emit_isk12(i);
|
||||
if (k)
|
||||
emit_dn(as, ai^k, dest, src);
|
||||
else
|
||||
emit_dnm(as, ai, dest, src, ra_allock(as, i, allow));
|
||||
}
|
||||
|
||||
/* Add offset to pointer. */
|
||||
static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
|
||||
{
|
||||
if (ofs)
|
||||
emit_opk(as, ofs < 0 ? A64I_SUBx : A64I_ADDx, r, r,
|
||||
ofs < 0 ? -ofs : ofs, rset_exclude(RSET_GPR, r));
|
||||
}
|
||||
|
||||
#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
|
||||
|
||||
@@ -1,293 +0,0 @@
|
||||
/*
|
||||
** MIPS instruction emitter.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#if LJ_64
|
||||
static intptr_t get_k64val(IRIns *ir)
|
||||
{
|
||||
if (ir->o == IR_KINT64) {
|
||||
return (intptr_t)ir_kint64(ir)->u64;
|
||||
} else if (ir->o == IR_KGC) {
|
||||
return (intptr_t)ir_kgc(ir);
|
||||
} else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {
|
||||
return (intptr_t)ir_kptr(ir);
|
||||
} else {
|
||||
lua_assert(ir->o == IR_KINT || ir->o == IR_KNULL);
|
||||
return ir->i; /* Sign-extended. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LJ_64
|
||||
#define get_kval(ir) get_k64val(ir)
|
||||
#else
|
||||
#define get_kval(ir) ((ir)->i)
|
||||
#endif
|
||||
|
||||
/* -- Emit basic instructions --------------------------------------------- */
|
||||
|
||||
static void emit_dst(ASMState *as, MIPSIns mi, Reg rd, Reg rs, Reg rt)
|
||||
{
|
||||
*--as->mcp = mi | MIPSF_D(rd) | MIPSF_S(rs) | MIPSF_T(rt);
|
||||
}
|
||||
|
||||
static void emit_dta(ASMState *as, MIPSIns mi, Reg rd, Reg rt, uint32_t a)
|
||||
{
|
||||
*--as->mcp = mi | MIPSF_D(rd) | MIPSF_T(rt) | MIPSF_A(a);
|
||||
}
|
||||
|
||||
#define emit_ds(as, mi, rd, rs) emit_dst(as, (mi), (rd), (rs), 0)
|
||||
#define emit_tg(as, mi, rt, rg) emit_dst(as, (mi), (rg)&31, 0, (rt))
|
||||
|
||||
static void emit_tsi(ASMState *as, MIPSIns mi, Reg rt, Reg rs, int32_t i)
|
||||
{
|
||||
*--as->mcp = mi | MIPSF_T(rt) | MIPSF_S(rs) | (i & 0xffff);
|
||||
}
|
||||
|
||||
#define emit_ti(as, mi, rt, i) emit_tsi(as, (mi), (rt), 0, (i))
|
||||
#define emit_hsi(as, mi, rh, rs, i) emit_tsi(as, (mi), (rh) & 31, (rs), (i))
|
||||
|
||||
static void emit_fgh(ASMState *as, MIPSIns mi, Reg rf, Reg rg, Reg rh)
|
||||
{
|
||||
*--as->mcp = mi | MIPSF_F(rf&31) | MIPSF_G(rg&31) | MIPSF_H(rh&31);
|
||||
}
|
||||
|
||||
#define emit_fg(as, mi, rf, rg) emit_fgh(as, (mi), (rf), (rg), 0)
|
||||
|
||||
static void emit_rotr(ASMState *as, Reg dest, Reg src, Reg tmp, uint32_t shift)
|
||||
{
|
||||
if (LJ_64 || (as->flags & JIT_F_MIPSXXR2)) {
|
||||
emit_dta(as, MIPSI_ROTR, dest, src, shift);
|
||||
} else {
|
||||
emit_dst(as, MIPSI_OR, dest, dest, tmp);
|
||||
emit_dta(as, MIPSI_SLL, dest, src, (-shift)&31);
|
||||
emit_dta(as, MIPSI_SRL, tmp, src, shift);
|
||||
}
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
static void emit_tsml(ASMState *as, MIPSIns mi, Reg rt, Reg rs, uint32_t msb,
|
||||
uint32_t lsb)
|
||||
{
|
||||
*--as->mcp = mi | MIPSF_T(rt) | MIPSF_S(rs) | MIPSF_M(msb) | MIPSF_L(lsb);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- Emit loads/stores --------------------------------------------------- */
|
||||
|
||||
/* Prefer rematerialization of BASE/L from global_State over spills. */
|
||||
#define emit_canremat(ref) ((ref) <= REF_BASE)
|
||||
|
||||
/* Try to find a one step delta relative to another constant. */
|
||||
static int emit_kdelta1(ASMState *as, Reg t, intptr_t i)
|
||||
{
|
||||
RegSet work = ~as->freeset & RSET_GPR;
|
||||
while (work) {
|
||||
Reg r = rset_picktop(work);
|
||||
IRRef ref = regcost_ref(as->cost[r]);
|
||||
lua_assert(r != t);
|
||||
if (ref < ASMREF_L) {
|
||||
intptr_t delta = (intptr_t)((uintptr_t)i -
|
||||
(uintptr_t)(ra_iskref(ref) ? ra_krefk(as, ref) : get_kval(IR(ref))));
|
||||
if (checki16(delta)) {
|
||||
emit_tsi(as, MIPSI_AADDIU, t, r, delta);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
rset_clear(work, r);
|
||||
}
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
||||
/* Load a 32 bit constant into a GPR. */
|
||||
static void emit_loadi(ASMState *as, Reg r, int32_t i)
|
||||
{
|
||||
if (checki16(i)) {
|
||||
emit_ti(as, MIPSI_LI, r, i);
|
||||
} else {
|
||||
if ((i & 0xffff)) {
|
||||
intptr_t jgl = (intptr_t)(void *)J2G(as->J);
|
||||
if ((uintptr_t)(i-jgl) < 65536) {
|
||||
emit_tsi(as, MIPSI_ADDIU, r, RID_JGL, i-jgl-32768);
|
||||
return;
|
||||
} else if (emit_kdelta1(as, r, i)) {
|
||||
return;
|
||||
} else if ((i >> 16) == 0) {
|
||||
emit_tsi(as, MIPSI_ORI, r, RID_ZERO, i);
|
||||
return;
|
||||
}
|
||||
emit_tsi(as, MIPSI_ORI, r, r, i);
|
||||
}
|
||||
emit_ti(as, MIPSI_LUI, r, (i >> 16));
|
||||
}
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
/* Load a 64 bit constant into a GPR. */
|
||||
static void emit_loadu64(ASMState *as, Reg r, uint64_t u64)
|
||||
{
|
||||
if (checki32((int64_t)u64)) {
|
||||
emit_loadi(as, r, (int32_t)u64);
|
||||
} else {
|
||||
uint64_t delta = u64 - (uint64_t)(void *)J2G(as->J);
|
||||
if (delta < 65536) {
|
||||
emit_tsi(as, MIPSI_DADDIU, r, RID_JGL, (int32_t)(delta-32768));
|
||||
} else if (emit_kdelta1(as, r, (intptr_t)u64)) {
|
||||
return;
|
||||
} else {
|
||||
if ((u64 & 0xffff)) {
|
||||
emit_tsi(as, MIPSI_ORI, r, r, u64 & 0xffff);
|
||||
}
|
||||
if (((u64 >> 16) & 0xffff)) {
|
||||
emit_dta(as, MIPSI_DSLL, r, r, 16);
|
||||
emit_tsi(as, MIPSI_ORI, r, r, (u64 >> 16) & 0xffff);
|
||||
emit_dta(as, MIPSI_DSLL, r, r, 16);
|
||||
} else {
|
||||
emit_dta(as, MIPSI_DSLL32, r, r, 0);
|
||||
}
|
||||
emit_loadi(as, r, (int32_t)(u64 >> 32));
|
||||
}
|
||||
/* TODO: There are probably more optimization opportunities. */
|
||||
}
|
||||
}
|
||||
|
||||
#define emit_loada(as, r, addr) emit_loadu64(as, (r), u64ptr((addr)))
|
||||
#else
|
||||
#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
|
||||
#endif
|
||||
|
||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
|
||||
static void ra_allockreg(ASMState *as, intptr_t k, Reg r);
|
||||
|
||||
/* Get/set from constant pointer. */
|
||||
static void emit_lsptr(ASMState *as, MIPSIns mi, Reg r, void *p, RegSet allow)
|
||||
{
|
||||
intptr_t jgl = (intptr_t)(J2G(as->J));
|
||||
intptr_t i = (intptr_t)(p);
|
||||
Reg base;
|
||||
if ((uint32_t)(i-jgl) < 65536) {
|
||||
i = i-jgl-32768;
|
||||
base = RID_JGL;
|
||||
} else {
|
||||
base = ra_allock(as, i-(int16_t)i, allow);
|
||||
}
|
||||
emit_tsi(as, mi, r, base, i);
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||
{
|
||||
const uint64_t *k = &ir_k64(ir)->u64;
|
||||
Reg r64 = r;
|
||||
if (rset_test(RSET_FPR, r)) {
|
||||
r64 = RID_TMP;
|
||||
emit_tg(as, MIPSI_DMTC1, r64, r);
|
||||
}
|
||||
if ((uint32_t)((intptr_t)k-(intptr_t)J2G(as->J)) < 65536)
|
||||
emit_lsptr(as, MIPSI_LD, r64, (void *)k, 0);
|
||||
else
|
||||
emit_loadu64(as, r64, *k);
|
||||
}
|
||||
#else
|
||||
#define emit_loadk64(as, r, ir) \
|
||||
emit_lsptr(as, MIPSI_LDC1, ((r) & 31), (void *)&ir_knum((ir))->u64, RSET_GPR)
|
||||
#endif
|
||||
|
||||
/* Get/set global_State fields. */
|
||||
static void emit_lsglptr(ASMState *as, MIPSIns mi, Reg r, int32_t ofs)
|
||||
{
|
||||
emit_tsi(as, mi, r, RID_JGL, ofs-32768);
|
||||
}
|
||||
|
||||
#define emit_getgl(as, r, field) \
|
||||
emit_lsglptr(as, MIPSI_AL, (r), (int32_t)offsetof(global_State, field))
|
||||
#define emit_setgl(as, r, field) \
|
||||
emit_lsglptr(as, MIPSI_AS, (r), (int32_t)offsetof(global_State, field))
|
||||
|
||||
/* Trace number is determined from per-trace exit stubs. */
|
||||
#define emit_setvmstate(as, i) UNUSED(i)
|
||||
|
||||
/* -- Emit control-flow instructions -------------------------------------- */
|
||||
|
||||
/* Label for internal jumps. */
|
||||
typedef MCode *MCLabel;
|
||||
|
||||
/* Return label pointing to current PC. */
|
||||
#define emit_label(as) ((as)->mcp)
|
||||
|
||||
static void emit_branch(ASMState *as, MIPSIns mi, Reg rs, Reg rt, MCode *target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(((delta + 0x8000) >> 16) == 0);
|
||||
*--p = mi | MIPSF_S(rs) | MIPSF_T(rt) | ((uint32_t)delta & 0xffffu);
|
||||
as->mcp = p;
|
||||
}
|
||||
|
||||
static void emit_jmp(ASMState *as, MCode *target)
|
||||
{
|
||||
*--as->mcp = MIPSI_NOP;
|
||||
emit_branch(as, MIPSI_B, RID_ZERO, RID_ZERO, (target));
|
||||
}
|
||||
|
||||
static void emit_call(ASMState *as, void *target, int needcfa)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
*--p = MIPSI_NOP;
|
||||
if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) {
|
||||
*--p = (((uintptr_t)target & 1) ? MIPSI_JALX : MIPSI_JAL) |
|
||||
(((uintptr_t)target >>2) & 0x03ffffffu);
|
||||
} else { /* Target out of range: need indirect call. */
|
||||
*--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR);
|
||||
needcfa = 1;
|
||||
}
|
||||
as->mcp = p;
|
||||
if (needcfa) ra_allockreg(as, (intptr_t)target, RID_CFUNCADDR);
|
||||
}
|
||||
|
||||
/* -- Emit generic operations --------------------------------------------- */
|
||||
|
||||
#define emit_move(as, dst, src) \
|
||||
emit_ds(as, MIPSI_MOVE, (dst), (src))
|
||||
|
||||
/* Generic move between two regs. */
|
||||
static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
|
||||
{
|
||||
if (dst < RID_MAX_GPR)
|
||||
emit_move(as, dst, src);
|
||||
else
|
||||
emit_fg(as, irt_isnum(ir->t) ? MIPSI_MOV_D : MIPSI_MOV_S, dst, src);
|
||||
}
|
||||
|
||||
/* Generic load of register with base and (small) offset address. */
|
||||
static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r < RID_MAX_GPR)
|
||||
emit_tsi(as, irt_is64(ir->t) ? MIPSI_LD : MIPSI_LW, r, base, ofs);
|
||||
else
|
||||
emit_tsi(as, irt_isnum(ir->t) ? MIPSI_LDC1 : MIPSI_LWC1,
|
||||
(r & 31), base, ofs);
|
||||
}
|
||||
|
||||
/* Generic store of register with base and (small) offset address. */
|
||||
static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r < RID_MAX_GPR)
|
||||
emit_tsi(as, irt_is64(ir->t) ? MIPSI_SD : MIPSI_SW, r, base, ofs);
|
||||
else
|
||||
emit_tsi(as, irt_isnum(ir->t) ? MIPSI_SDC1 : MIPSI_SWC1,
|
||||
(r&31), base, ofs);
|
||||
}
|
||||
|
||||
/* Add offset to pointer. */
|
||||
static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
|
||||
{
|
||||
if (ofs) {
|
||||
lua_assert(checki16(ofs));
|
||||
emit_tsi(as, MIPSI_AADDIU, r, r, ofs);
|
||||
}
|
||||
}
|
||||
|
||||
#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
** PPC instruction emitter.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Emit basic instructions --------------------------------------------- */
|
||||
|
||||
static void emit_tab(ASMState *as, PPCIns pi, Reg rt, Reg ra, Reg rb)
|
||||
{
|
||||
*--as->mcp = pi | PPCF_T(rt) | PPCF_A(ra) | PPCF_B(rb);
|
||||
}
|
||||
|
||||
#define emit_asb(as, pi, ra, rs, rb) emit_tab(as, (pi), (rs), (ra), (rb))
|
||||
#define emit_as(as, pi, ra, rs) emit_tab(as, (pi), (rs), (ra), 0)
|
||||
#define emit_ab(as, pi, ra, rb) emit_tab(as, (pi), 0, (ra), (rb))
|
||||
|
||||
static void emit_tai(ASMState *as, PPCIns pi, Reg rt, Reg ra, int32_t i)
|
||||
{
|
||||
*--as->mcp = pi | PPCF_T(rt) | PPCF_A(ra) | (i & 0xffff);
|
||||
}
|
||||
|
||||
#define emit_ti(as, pi, rt, i) emit_tai(as, (pi), (rt), 0, (i))
|
||||
#define emit_ai(as, pi, ra, i) emit_tai(as, (pi), 0, (ra), (i))
|
||||
#define emit_asi(as, pi, ra, rs, i) emit_tai(as, (pi), (rs), (ra), (i))
|
||||
|
||||
#define emit_fab(as, pi, rf, ra, rb) \
|
||||
emit_tab(as, (pi), (rf)&31, (ra)&31, (rb)&31)
|
||||
#define emit_fb(as, pi, rf, rb) emit_tab(as, (pi), (rf)&31, 0, (rb)&31)
|
||||
#define emit_fac(as, pi, rf, ra, rc) \
|
||||
emit_tab(as, (pi) | PPCF_C((rc) & 31), (rf)&31, (ra)&31, 0)
|
||||
#define emit_facb(as, pi, rf, ra, rc, rb) \
|
||||
emit_tab(as, (pi) | PPCF_C((rc) & 31), (rf)&31, (ra)&31, (rb)&31)
|
||||
#define emit_fai(as, pi, rf, ra, i) emit_tai(as, (pi), (rf)&31, (ra), (i))
|
||||
|
||||
static void emit_rot(ASMState *as, PPCIns pi, Reg ra, Reg rs,
|
||||
int32_t n, int32_t b, int32_t e)
|
||||
{
|
||||
*--as->mcp = pi | PPCF_T(rs) | PPCF_A(ra) | PPCF_B(n) |
|
||||
PPCF_MB(b) | PPCF_ME(e);
|
||||
}
|
||||
|
||||
static void emit_slwi(ASMState *as, Reg ra, Reg rs, int32_t n)
|
||||
{
|
||||
lua_assert(n >= 0 && n < 32);
|
||||
emit_rot(as, PPCI_RLWINM, ra, rs, n, 0, 31-n);
|
||||
}
|
||||
|
||||
static void emit_rotlwi(ASMState *as, Reg ra, Reg rs, int32_t n)
|
||||
{
|
||||
lua_assert(n >= 0 && n < 32);
|
||||
emit_rot(as, PPCI_RLWINM, ra, rs, n, 0, 31);
|
||||
}
|
||||
|
||||
/* -- Emit loads/stores --------------------------------------------------- */
|
||||
|
||||
/* Prefer rematerialization of BASE/L from global_State over spills. */
|
||||
#define emit_canremat(ref) ((ref) <= REF_BASE)
|
||||
|
||||
/* Try to find a one step delta relative to another constant. */
|
||||
static int emit_kdelta1(ASMState *as, Reg t, int32_t i)
|
||||
{
|
||||
RegSet work = ~as->freeset & RSET_GPR;
|
||||
while (work) {
|
||||
Reg r = rset_picktop(work);
|
||||
IRRef ref = regcost_ref(as->cost[r]);
|
||||
lua_assert(r != t);
|
||||
if (ref < ASMREF_L) {
|
||||
int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
|
||||
if (checki16(delta)) {
|
||||
emit_tai(as, PPCI_ADDI, t, r, delta);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
rset_clear(work, r);
|
||||
}
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
||||
/* Load a 32 bit constant into a GPR. */
|
||||
static void emit_loadi(ASMState *as, Reg r, int32_t i)
|
||||
{
|
||||
if (checki16(i)) {
|
||||
emit_ti(as, PPCI_LI, r, i);
|
||||
} else {
|
||||
if ((i & 0xffff)) {
|
||||
int32_t jgl = i32ptr(J2G(as->J));
|
||||
if ((uint32_t)(i-jgl) < 65536) {
|
||||
emit_tai(as, PPCI_ADDI, r, RID_JGL, i-jgl-32768);
|
||||
return;
|
||||
} else if (emit_kdelta1(as, r, i)) {
|
||||
return;
|
||||
}
|
||||
emit_asi(as, PPCI_ORI, r, r, i);
|
||||
}
|
||||
emit_ti(as, PPCI_LIS, r, (i >> 16));
|
||||
}
|
||||
}
|
||||
|
||||
#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
|
||||
|
||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
|
||||
|
||||
/* Get/set from constant pointer. */
|
||||
static void emit_lsptr(ASMState *as, PPCIns pi, Reg r, void *p, RegSet allow)
|
||||
{
|
||||
int32_t jgl = i32ptr(J2G(as->J));
|
||||
int32_t i = i32ptr(p);
|
||||
Reg base;
|
||||
if ((uint32_t)(i-jgl) < 65536) {
|
||||
i = i-jgl-32768;
|
||||
base = RID_JGL;
|
||||
} else {
|
||||
base = ra_allock(as, i-(int16_t)i, allow);
|
||||
}
|
||||
emit_tai(as, pi, r, base, i);
|
||||
}
|
||||
|
||||
#define emit_loadk64(as, r, ir) \
|
||||
emit_lsptr(as, PPCI_LFD, ((r) & 31), (void *)&ir_knum((ir))->u64, RSET_GPR)
|
||||
|
||||
/* Get/set global_State fields. */
|
||||
static void emit_lsglptr(ASMState *as, PPCIns pi, Reg r, int32_t ofs)
|
||||
{
|
||||
emit_tai(as, pi, r, RID_JGL, ofs-32768);
|
||||
}
|
||||
|
||||
#define emit_getgl(as, r, field) \
|
||||
emit_lsglptr(as, PPCI_LWZ, (r), (int32_t)offsetof(global_State, field))
|
||||
#define emit_setgl(as, r, field) \
|
||||
emit_lsglptr(as, PPCI_STW, (r), (int32_t)offsetof(global_State, field))
|
||||
|
||||
/* Trace number is determined from per-trace exit stubs. */
|
||||
#define emit_setvmstate(as, i) UNUSED(i)
|
||||
|
||||
/* -- Emit control-flow instructions -------------------------------------- */
|
||||
|
||||
/* Label for internal jumps. */
|
||||
typedef MCode *MCLabel;
|
||||
|
||||
/* Return label pointing to current PC. */
|
||||
#define emit_label(as) ((as)->mcp)
|
||||
|
||||
static void emit_condbranch(ASMState *as, PPCIns pi, PPCCC cc, MCode *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = (char *)target - (char *)p;
|
||||
lua_assert(((delta + 0x8000) >> 16) == 0);
|
||||
pi ^= (delta & 0x8000) * (PPCF_Y/0x8000);
|
||||
*p = pi | PPCF_CC(cc) | ((uint32_t)delta & 0xffffu);
|
||||
}
|
||||
|
||||
static void emit_jmp(ASMState *as, MCode *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = (char *)target - (char *)p;
|
||||
*p = PPCI_B | (delta & 0x03fffffcu);
|
||||
}
|
||||
|
||||
static void emit_call(ASMState *as, void *target)
|
||||
{
|
||||
MCode *p = --as->mcp;
|
||||
ptrdiff_t delta = (char *)target - (char *)p;
|
||||
if ((((delta>>2) + 0x00800000) >> 24) == 0) {
|
||||
*p = PPCI_BL | (delta & 0x03fffffcu);
|
||||
} else { /* Target out of range: need indirect call. Don't use arg reg. */
|
||||
RegSet allow = RSET_GPR & ~RSET_RANGE(RID_R0, REGARG_LASTGPR+1);
|
||||
Reg r = ra_allock(as, i32ptr(target), allow);
|
||||
*p = PPCI_BCTRL;
|
||||
p[-1] = PPCI_MTCTR | PPCF_T(r);
|
||||
as->mcp = p-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Emit generic operations --------------------------------------------- */
|
||||
|
||||
#define emit_mr(as, dst, src) \
|
||||
emit_asb(as, PPCI_MR, (dst), (src), (src))
|
||||
|
||||
/* Generic move between two regs. */
|
||||
static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
|
||||
{
|
||||
UNUSED(ir);
|
||||
if (dst < RID_MAX_GPR)
|
||||
emit_mr(as, dst, src);
|
||||
else
|
||||
emit_fb(as, PPCI_FMR, dst, src);
|
||||
}
|
||||
|
||||
/* Generic load of register with base and (small) offset address. */
|
||||
static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r < RID_MAX_GPR)
|
||||
emit_tai(as, PPCI_LWZ, r, base, ofs);
|
||||
else
|
||||
emit_fai(as, irt_isnum(ir->t) ? PPCI_LFD : PPCI_LFS, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Generic store of register with base and (small) offset address. */
|
||||
static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r < RID_MAX_GPR)
|
||||
emit_tai(as, PPCI_STW, r, base, ofs);
|
||||
else
|
||||
emit_fai(as, irt_isnum(ir->t) ? PPCI_STFD : PPCI_STFS, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Emit a compare (for equality) with a constant operand. */
|
||||
static void emit_cmpi(ASMState *as, Reg r, int32_t k)
|
||||
{
|
||||
if (checki16(k)) {
|
||||
emit_ai(as, PPCI_CMPWI, r, k);
|
||||
} else if (checku16(k)) {
|
||||
emit_ai(as, PPCI_CMPLWI, r, k);
|
||||
} else {
|
||||
emit_ai(as, PPCI_CMPLWI, RID_TMP, k);
|
||||
emit_asi(as, PPCI_XORIS, RID_TMP, r, (k >> 16));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add offset to pointer. */
|
||||
static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
|
||||
{
|
||||
if (ofs) {
|
||||
emit_tai(as, PPCI_ADDI, r, r, ofs);
|
||||
if (!checki16(ofs))
|
||||
emit_tai(as, PPCI_ADDIS, r, r, (ofs + 32768) >> 16);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_spsub(ASMState *as, int32_t ofs)
|
||||
{
|
||||
if (ofs) {
|
||||
emit_tai(as, PPCI_STWU, RID_TMP, RID_SP, -ofs);
|
||||
emit_tai(as, PPCI_ADDI, RID_TMP, RID_SP,
|
||||
CFRAME_SIZE + (as->parent ? as->parent->spadjust : 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
/*
|
||||
** x86/x64 instruction emitter.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Emit basic instructions --------------------------------------------- */
|
||||
|
||||
#define MODRM(mode, r1, r2) ((MCode)((mode)+(((r1)&7)<<3)+((r2)&7)))
|
||||
|
||||
#if LJ_64
|
||||
#define REXRB(p, rr, rb) \
|
||||
{ MCode rex = 0x40 + (((rr)>>1)&4) + (((rb)>>3)&1); \
|
||||
if (rex != 0x40) *--(p) = rex; }
|
||||
#define FORCE_REX 0x200
|
||||
#define REX_64 (FORCE_REX|0x080000)
|
||||
#define VEX_64 0x800000
|
||||
#else
|
||||
#define REXRB(p, rr, rb) ((void)0)
|
||||
#define FORCE_REX 0
|
||||
#define REX_64 0
|
||||
#define VEX_64 0
|
||||
#endif
|
||||
#if LJ_GC64
|
||||
#define REX_GC64 REX_64
|
||||
#else
|
||||
#define REX_GC64 0
|
||||
#endif
|
||||
|
||||
#define emit_i8(as, i) (*--as->mcp = (MCode)(i))
|
||||
#define emit_i32(as, i) (*(int32_t *)(as->mcp-4) = (i), as->mcp -= 4)
|
||||
#define emit_u32(as, u) (*(uint32_t *)(as->mcp-4) = (u), as->mcp -= 4)
|
||||
|
||||
#define emit_x87op(as, xo) \
|
||||
(*(uint16_t *)(as->mcp-2) = (uint16_t)(xo), as->mcp -= 2)
|
||||
|
||||
/* op */
|
||||
static LJ_AINLINE MCode *emit_op(x86Op xo, Reg rr, Reg rb, Reg rx,
|
||||
MCode *p, int delta)
|
||||
{
|
||||
int n = (int8_t)xo;
|
||||
if (n == -60) { /* VEX-encoded instruction */
|
||||
#if LJ_64
|
||||
xo ^= (((rr>>1)&4)+((rx>>2)&2)+((rb>>3)&1))<<13;
|
||||
#endif
|
||||
*(uint32_t *)(p+delta-5) = (uint32_t)xo;
|
||||
return p+delta-5;
|
||||
}
|
||||
#if defined(__GNUC__)
|
||||
if (__builtin_constant_p(xo) && n == -2)
|
||||
p[delta-2] = (MCode)(xo >> 24);
|
||||
else if (__builtin_constant_p(xo) && n == -3)
|
||||
*(uint16_t *)(p+delta-3) = (uint16_t)(xo >> 16);
|
||||
else
|
||||
#endif
|
||||
*(uint32_t *)(p+delta-5) = (uint32_t)xo;
|
||||
p += n + delta;
|
||||
#if LJ_64
|
||||
{
|
||||
uint32_t rex = 0x40 + ((rr>>1)&(4+(FORCE_REX>>1)))+((rx>>2)&2)+((rb>>3)&1);
|
||||
if (rex != 0x40) {
|
||||
rex |= (rr >> 16);
|
||||
if (n == -4) { *p = (MCode)rex; rex = (MCode)(xo >> 8); }
|
||||
else if ((xo & 0xffffff) == 0x6600fd) { *p = (MCode)rex; rex = 0x66; }
|
||||
*--p = (MCode)rex;
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED(rr); UNUSED(rb); UNUSED(rx);
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
/* op + modrm */
|
||||
#define emit_opm(xo, mode, rr, rb, p, delta) \
|
||||
(p[(delta)-1] = MODRM((mode), (rr), (rb)), \
|
||||
emit_op((xo), (rr), (rb), 0, (p), (delta)))
|
||||
|
||||
/* op + modrm + sib */
|
||||
#define emit_opmx(xo, mode, scale, rr, rb, rx, p) \
|
||||
(p[-1] = MODRM((scale), (rx), (rb)), \
|
||||
p[-2] = MODRM((mode), (rr), RID_ESP), \
|
||||
emit_op((xo), (rr), (rb), (rx), (p), -1))
|
||||
|
||||
/* op r1, r2 */
|
||||
static void emit_rr(ASMState *as, x86Op xo, Reg r1, Reg r2)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
as->mcp = emit_opm(xo, XM_REG, r1, r2, p, 0);
|
||||
}
|
||||
|
||||
#if LJ_64 && defined(LUA_USE_ASSERT)
|
||||
/* [addr] is sign-extended in x64 and must be in lower 2G (not 4G). */
|
||||
static int32_t ptr2addr(const void *p)
|
||||
{
|
||||
lua_assert((uintptr_t)p < (uintptr_t)0x80000000);
|
||||
return i32ptr(p);
|
||||
}
|
||||
#else
|
||||
#define ptr2addr(p) (i32ptr((p)))
|
||||
#endif
|
||||
|
||||
/* op r, [base+ofs] */
|
||||
static void emit_rmro(ASMState *as, x86Op xo, Reg rr, Reg rb, int32_t ofs)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
x86Mode mode;
|
||||
if (ra_hasreg(rb)) {
|
||||
if (LJ_GC64 && rb == RID_RIP) {
|
||||
mode = XM_OFS0;
|
||||
p -= 4;
|
||||
*(int32_t *)p = ofs;
|
||||
} else if (ofs == 0 && (rb&7) != RID_EBP) {
|
||||
mode = XM_OFS0;
|
||||
} else if (checki8(ofs)) {
|
||||
*--p = (MCode)ofs;
|
||||
mode = XM_OFS8;
|
||||
} else {
|
||||
p -= 4;
|
||||
*(int32_t *)p = ofs;
|
||||
mode = XM_OFS32;
|
||||
}
|
||||
if ((rb&7) == RID_ESP)
|
||||
*--p = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
|
||||
} else {
|
||||
*(int32_t *)(p-4) = ofs;
|
||||
#if LJ_64
|
||||
p[-5] = MODRM(XM_SCALE1, RID_ESP, RID_EBP);
|
||||
p -= 5;
|
||||
rb = RID_ESP;
|
||||
#else
|
||||
p -= 4;
|
||||
rb = RID_EBP;
|
||||
#endif
|
||||
mode = XM_OFS0;
|
||||
}
|
||||
as->mcp = emit_opm(xo, mode, rr, rb, p, 0);
|
||||
}
|
||||
|
||||
/* op r, [base+idx*scale+ofs] */
|
||||
static void emit_rmrxo(ASMState *as, x86Op xo, Reg rr, Reg rb, Reg rx,
|
||||
x86Mode scale, int32_t ofs)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
x86Mode mode;
|
||||
if (ofs == 0 && (rb&7) != RID_EBP) {
|
||||
mode = XM_OFS0;
|
||||
} else if (checki8(ofs)) {
|
||||
mode = XM_OFS8;
|
||||
*--p = (MCode)ofs;
|
||||
} else {
|
||||
mode = XM_OFS32;
|
||||
p -= 4;
|
||||
*(int32_t *)p = ofs;
|
||||
}
|
||||
as->mcp = emit_opmx(xo, mode, scale, rr, rb, rx, p);
|
||||
}
|
||||
|
||||
/* op r, i */
|
||||
static void emit_gri(ASMState *as, x86Group xg, Reg rb, int32_t i)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
x86Op xo;
|
||||
if (checki8(i)) {
|
||||
*--p = (MCode)i;
|
||||
xo = XG_TOXOi8(xg);
|
||||
} else {
|
||||
p -= 4;
|
||||
*(int32_t *)p = i;
|
||||
xo = XG_TOXOi(xg);
|
||||
}
|
||||
as->mcp = emit_opm(xo, XM_REG, (Reg)(xg & 7) | (rb & REX_64), rb, p, 0);
|
||||
}
|
||||
|
||||
/* op [base+ofs], i */
|
||||
static void emit_gmroi(ASMState *as, x86Group xg, Reg rb, int32_t ofs,
|
||||
int32_t i)
|
||||
{
|
||||
x86Op xo;
|
||||
if (checki8(i)) {
|
||||
emit_i8(as, i);
|
||||
xo = XG_TOXOi8(xg);
|
||||
} else {
|
||||
emit_i32(as, i);
|
||||
xo = XG_TOXOi(xg);
|
||||
}
|
||||
emit_rmro(as, xo, (Reg)(xg & 7), rb, ofs);
|
||||
}
|
||||
|
||||
#define emit_shifti(as, xg, r, i) \
|
||||
(emit_i8(as, (i)), emit_rr(as, XO_SHIFTi, (Reg)(xg), (r)))
|
||||
|
||||
/* op r, rm/mrm */
|
||||
static void emit_mrm(ASMState *as, x86Op xo, Reg rr, Reg rb)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
x86Mode mode = XM_REG;
|
||||
if (rb == RID_MRM) {
|
||||
rb = as->mrm.base;
|
||||
if (rb == RID_NONE) {
|
||||
rb = RID_EBP;
|
||||
mode = XM_OFS0;
|
||||
p -= 4;
|
||||
*(int32_t *)p = as->mrm.ofs;
|
||||
if (as->mrm.idx != RID_NONE)
|
||||
goto mrmidx;
|
||||
#if LJ_64
|
||||
*--p = MODRM(XM_SCALE1, RID_ESP, RID_EBP);
|
||||
rb = RID_ESP;
|
||||
#endif
|
||||
} else if (LJ_GC64 && rb == RID_RIP) {
|
||||
lua_assert(as->mrm.idx == RID_NONE);
|
||||
mode = XM_OFS0;
|
||||
p -= 4;
|
||||
*(int32_t *)p = as->mrm.ofs;
|
||||
} else {
|
||||
if (as->mrm.ofs == 0 && (rb&7) != RID_EBP) {
|
||||
mode = XM_OFS0;
|
||||
} else if (checki8(as->mrm.ofs)) {
|
||||
*--p = (MCode)as->mrm.ofs;
|
||||
mode = XM_OFS8;
|
||||
} else {
|
||||
p -= 4;
|
||||
*(int32_t *)p = as->mrm.ofs;
|
||||
mode = XM_OFS32;
|
||||
}
|
||||
if (as->mrm.idx != RID_NONE) {
|
||||
mrmidx:
|
||||
as->mcp = emit_opmx(xo, mode, as->mrm.scale, rr, rb, as->mrm.idx, p);
|
||||
return;
|
||||
}
|
||||
if ((rb&7) == RID_ESP)
|
||||
*--p = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
|
||||
}
|
||||
}
|
||||
as->mcp = emit_opm(xo, mode, rr, rb, p, 0);
|
||||
}
|
||||
|
||||
/* op rm/mrm, i */
|
||||
static void emit_gmrmi(ASMState *as, x86Group xg, Reg rb, int32_t i)
|
||||
{
|
||||
x86Op xo;
|
||||
if (checki8(i)) {
|
||||
emit_i8(as, i);
|
||||
xo = XG_TOXOi8(xg);
|
||||
} else {
|
||||
emit_i32(as, i);
|
||||
xo = XG_TOXOi(xg);
|
||||
}
|
||||
emit_mrm(as, xo, (Reg)(xg & 7) | (rb & REX_64), (rb & ~REX_64));
|
||||
}
|
||||
|
||||
/* -- Emit loads/stores --------------------------------------------------- */
|
||||
|
||||
/* mov [base+ofs], i */
|
||||
static void emit_movmroi(ASMState *as, Reg base, int32_t ofs, int32_t i)
|
||||
{
|
||||
emit_i32(as, i);
|
||||
emit_rmro(as, XO_MOVmi, 0, base, ofs);
|
||||
}
|
||||
|
||||
/* mov [base+ofs], r */
|
||||
#define emit_movtomro(as, r, base, ofs) \
|
||||
emit_rmro(as, XO_MOVto, (r), (base), (ofs))
|
||||
|
||||
/* Get/set global_State fields. */
|
||||
#define emit_opgl(as, xo, r, field) \
|
||||
emit_rma(as, (xo), (r), (void *)&J2G(as->J)->field)
|
||||
#define emit_getgl(as, r, field) emit_opgl(as, XO_MOV, (r)|REX_GC64, field)
|
||||
#define emit_setgl(as, r, field) emit_opgl(as, XO_MOVto, (r)|REX_GC64, field)
|
||||
|
||||
#define emit_setvmstate(as, i) \
|
||||
(emit_i32(as, i), emit_opgl(as, XO_MOVmi, 0, vmstate))
|
||||
|
||||
/* mov r, i / xor r, r */
|
||||
static void emit_loadi(ASMState *as, Reg r, int32_t i)
|
||||
{
|
||||
/* XOR r,r is shorter, but modifies the flags. This is bad for HIOP. */
|
||||
if (i == 0 && !(LJ_32 && (IR(as->curins)->o == IR_HIOP ||
|
||||
(as->curins+1 < as->T->nins &&
|
||||
IR(as->curins+1)->o == IR_HIOP)))) {
|
||||
emit_rr(as, XO_ARITH(XOg_XOR), r, r);
|
||||
} else {
|
||||
MCode *p = as->mcp;
|
||||
*(int32_t *)(p-4) = i;
|
||||
p[-5] = (MCode)(XI_MOVri+(r&7));
|
||||
p -= 5;
|
||||
REXRB(p, 0, r);
|
||||
as->mcp = p;
|
||||
}
|
||||
}
|
||||
|
||||
#if LJ_GC64
|
||||
#define dispofs(as, k) \
|
||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)J2GG(as->J)->dispatch))
|
||||
#define mcpofs(as, k) \
|
||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)as->mcp))
|
||||
#define mctopofs(as, k) \
|
||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)as->mctop))
|
||||
/* mov r, addr */
|
||||
#define emit_loada(as, r, addr) \
|
||||
emit_loadu64(as, (r), (uintptr_t)(addr))
|
||||
#else
|
||||
/* mov r, addr */
|
||||
#define emit_loada(as, r, addr) \
|
||||
emit_loadi(as, (r), ptr2addr((addr)))
|
||||
#endif
|
||||
|
||||
#if LJ_64
|
||||
/* mov r, imm64 or shorter 32 bit extended load. */
|
||||
static void emit_loadu64(ASMState *as, Reg r, uint64_t u64)
|
||||
{
|
||||
if (checku32(u64)) { /* 32 bit load clears upper 32 bits. */
|
||||
emit_loadi(as, r, (int32_t)u64);
|
||||
} else if (checki32((int64_t)u64)) { /* Sign-extended 32 bit load. */
|
||||
MCode *p = as->mcp;
|
||||
*(int32_t *)(p-4) = (int32_t)u64;
|
||||
as->mcp = emit_opm(XO_MOVmi, XM_REG, REX_64, r, p, -4);
|
||||
#if LJ_GC64
|
||||
} else if (checki32(dispofs(as, u64))) {
|
||||
emit_rmro(as, XO_LEA, r|REX_64, RID_DISPATCH, (int32_t)dispofs(as, u64));
|
||||
} else if (checki32(mcpofs(as, u64)) && checki32(mctopofs(as, u64))) {
|
||||
/* Since as->realign assumes the code size doesn't change, check
|
||||
** RIP-relative addressing reachability for both as->mcp and as->mctop.
|
||||
*/
|
||||
emit_rmro(as, XO_LEA, r|REX_64, RID_RIP, (int32_t)mcpofs(as, u64));
|
||||
#endif
|
||||
} else { /* Full-size 64 bit load. */
|
||||
MCode *p = as->mcp;
|
||||
*(uint64_t *)(p-8) = u64;
|
||||
p[-9] = (MCode)(XI_MOVri+(r&7));
|
||||
p[-10] = 0x48 + ((r>>3)&1);
|
||||
p -= 10;
|
||||
as->mcp = p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* op r, [addr] */
|
||||
static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr)
|
||||
{
|
||||
#if LJ_GC64
|
||||
if (checki32(dispofs(as, addr))) {
|
||||
emit_rmro(as, xo, rr, RID_DISPATCH, (int32_t)dispofs(as, addr));
|
||||
} else if (checki32(mcpofs(as, addr)) && checki32(mctopofs(as, addr))) {
|
||||
emit_rmro(as, xo, rr, RID_RIP, (int32_t)mcpofs(as, addr));
|
||||
} else if (!checki32((intptr_t)addr) && (xo == XO_MOV || xo == XO_MOVSD)) {
|
||||
emit_rmro(as, xo, rr, rr, 0);
|
||||
emit_loadu64(as, rr, (uintptr_t)addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
*(int32_t *)(p-4) = ptr2addr(addr);
|
||||
#if LJ_64
|
||||
p[-5] = MODRM(XM_SCALE1, RID_ESP, RID_EBP);
|
||||
as->mcp = emit_opm(xo, XM_OFS0, rr, RID_ESP, p, -5);
|
||||
#else
|
||||
as->mcp = emit_opm(xo, XM_OFS0, rr, RID_EBP, p, -4);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Load 64 bit IR constant into register. */
|
||||
static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||
{
|
||||
Reg r64;
|
||||
x86Op xo;
|
||||
const uint64_t *k = &ir_k64(ir)->u64;
|
||||
if (rset_test(RSET_FPR, r)) {
|
||||
r64 = r;
|
||||
xo = XO_MOVSD;
|
||||
} else {
|
||||
r64 = r | REX_64;
|
||||
xo = XO_MOV;
|
||||
}
|
||||
if (*k == 0) {
|
||||
emit_rr(as, rset_test(RSET_FPR, r) ? XO_XORPS : XO_ARITH(XOg_XOR), r, r);
|
||||
#if LJ_GC64
|
||||
} else if (checki32((intptr_t)k) || checki32(dispofs(as, k)) ||
|
||||
(checki32(mcpofs(as, k)) && checki32(mctopofs(as, k)))) {
|
||||
emit_rma(as, xo, r64, k);
|
||||
} else {
|
||||
if (ir->i) {
|
||||
lua_assert(*k == *(uint64_t*)(as->mctop - ir->i));
|
||||
} else if (as->curins <= as->stopins && rset_test(RSET_GPR, r)) {
|
||||
emit_loadu64(as, r, *k);
|
||||
return;
|
||||
} else {
|
||||
/* If all else fails, add the FP constant at the MCode area bottom. */
|
||||
while ((uintptr_t)as->mcbot & 7) *as->mcbot++ = XI_INT3;
|
||||
*(uint64_t *)as->mcbot = *k;
|
||||
ir->i = (int32_t)(as->mctop - as->mcbot);
|
||||
as->mcbot += 8;
|
||||
as->mclim = as->mcbot + MCLIM_REDZONE;
|
||||
lj_mcode_commitbot(as->J, as->mcbot);
|
||||
}
|
||||
emit_rmro(as, xo, r64, RID_RIP, (int32_t)mcpofs(as, as->mctop - ir->i));
|
||||
#else
|
||||
} else {
|
||||
emit_rma(as, xo, r64, k);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Emit control-flow instructions -------------------------------------- */
|
||||
|
||||
/* Label for short jumps. */
|
||||
typedef MCode *MCLabel;
|
||||
|
||||
#if LJ_32 && LJ_HASFFI
|
||||
/* jmp short target */
|
||||
static void emit_sjmp(ASMState *as, MCLabel target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(delta == (int8_t)delta);
|
||||
p[-1] = (MCode)(int8_t)delta;
|
||||
p[-2] = XI_JMPs;
|
||||
as->mcp = p - 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* jcc short target */
|
||||
static void emit_sjcc(ASMState *as, int cc, MCLabel target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(delta == (int8_t)delta);
|
||||
p[-1] = (MCode)(int8_t)delta;
|
||||
p[-2] = (MCode)(XI_JCCs+(cc&15));
|
||||
as->mcp = p - 2;
|
||||
}
|
||||
|
||||
/* jcc short (pending target) */
|
||||
static MCLabel emit_sjcc_label(ASMState *as, int cc)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
p[-1] = 0;
|
||||
p[-2] = (MCode)(XI_JCCs+(cc&15));
|
||||
as->mcp = p - 2;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Fixup jcc short target. */
|
||||
static void emit_sfixup(ASMState *as, MCLabel source)
|
||||
{
|
||||
source[-1] = (MCode)(as->mcp-source);
|
||||
}
|
||||
|
||||
/* Return label pointing to current PC. */
|
||||
#define emit_label(as) ((as)->mcp)
|
||||
|
||||
/* Compute relative 32 bit offset for jump and call instructions. */
|
||||
static LJ_AINLINE int32_t jmprel(MCode *p, MCode *target)
|
||||
{
|
||||
ptrdiff_t delta = target - p;
|
||||
lua_assert(delta == (int32_t)delta);
|
||||
return (int32_t)delta;
|
||||
}
|
||||
|
||||
/* jcc target */
|
||||
static void emit_jcc(ASMState *as, int cc, MCode *target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
*(int32_t *)(p-4) = jmprel(p, target);
|
||||
p[-5] = (MCode)(XI_JCCn+(cc&15));
|
||||
p[-6] = 0x0f;
|
||||
as->mcp = p - 6;
|
||||
}
|
||||
|
||||
/* jmp target */
|
||||
static void emit_jmp(ASMState *as, MCode *target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
*(int32_t *)(p-4) = jmprel(p, target);
|
||||
p[-5] = XI_JMP;
|
||||
as->mcp = p - 5;
|
||||
}
|
||||
|
||||
/* call target */
|
||||
static void emit_call_(ASMState *as, MCode *target)
|
||||
{
|
||||
MCode *p = as->mcp;
|
||||
#if LJ_64
|
||||
if (target-p != (int32_t)(target-p)) {
|
||||
/* Assumes RID_RET is never an argument to calls and always clobbered. */
|
||||
emit_rr(as, XO_GROUP5, XOg_CALL, RID_RET);
|
||||
emit_loadu64(as, RID_RET, (uint64_t)target);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*(int32_t *)(p-4) = jmprel(p, target);
|
||||
p[-5] = XI_CALL;
|
||||
as->mcp = p - 5;
|
||||
}
|
||||
|
||||
#define emit_call(as, f) emit_call_(as, (MCode *)(void *)(f))
|
||||
|
||||
/* -- Emit generic operations --------------------------------------------- */
|
||||
|
||||
/* Use 64 bit operations to handle 64 bit IR types. */
|
||||
#if LJ_64
|
||||
#define REX_64IR(ir, r) ((r) + (irt_is64((ir)->t) ? REX_64 : 0))
|
||||
#define VEX_64IR(ir, r) ((r) + (irt_is64((ir)->t) ? VEX_64 : 0))
|
||||
#else
|
||||
#define REX_64IR(ir, r) (r)
|
||||
#define VEX_64IR(ir, r) (r)
|
||||
#endif
|
||||
|
||||
/* Generic move between two regs. */
|
||||
static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
|
||||
{
|
||||
UNUSED(ir);
|
||||
if (dst < RID_MAX_GPR)
|
||||
emit_rr(as, XO_MOV, REX_64IR(ir, dst), src);
|
||||
else
|
||||
emit_rr(as, XO_MOVAPS, dst, src);
|
||||
}
|
||||
|
||||
/* Generic load of register with base and (small) offset address. */
|
||||
static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r < RID_MAX_GPR)
|
||||
emit_rmro(as, XO_MOV, REX_64IR(ir, r), base, ofs);
|
||||
else
|
||||
emit_rmro(as, irt_isnum(ir->t) ? XO_MOVSD : XO_MOVSS, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Generic store of register with base and (small) offset address. */
|
||||
static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs)
|
||||
{
|
||||
if (r < RID_MAX_GPR)
|
||||
emit_rmro(as, XO_MOVto, REX_64IR(ir, r), base, ofs);
|
||||
else
|
||||
emit_rmro(as, irt_isnum(ir->t) ? XO_MOVSDto : XO_MOVSSto, r, base, ofs);
|
||||
}
|
||||
|
||||
/* Add offset to pointer. */
|
||||
static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
|
||||
{
|
||||
if (ofs) {
|
||||
if ((as->flags & JIT_F_LEA_AGU))
|
||||
emit_rmro(as, XO_LEA, r|REX_GC64, r, ofs);
|
||||
else
|
||||
emit_gri(as, XG_ARITHi(XOg_ADD), r|REX_GC64, ofs);
|
||||
}
|
||||
}
|
||||
|
||||
#define emit_spsub(as, ofs) emit_addptr(as, RID_ESP|REX_64, -(ofs))
|
||||
|
||||
/* Prefer rematerialization of BASE/L from global_State over spills. */
|
||||
#define emit_canremat(ref) ((ref) <= REF_BASE)
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
** Error handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ERR_H
|
||||
#define _LJ_ERR_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
typedef enum {
|
||||
#define ERRDEF(name, msg) \
|
||||
LJ_ERR_##name, LJ_ERR_##name##_ = LJ_ERR_##name + sizeof(msg)-1,
|
||||
#include "lj_errmsg.h"
|
||||
LJ_ERR__MAX
|
||||
} ErrMsg;
|
||||
|
||||
LJ_DATA const char *lj_err_allmsg;
|
||||
#define err2msg(em) (lj_err_allmsg+(int)(em))
|
||||
|
||||
LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em);
|
||||
LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode);
|
||||
LJ_FUNC_NORET void lj_err_mem(lua_State *L);
|
||||
LJ_FUNC_NORET void lj_err_run(lua_State *L);
|
||||
LJ_FUNC_NORET void lj_err_msg(lua_State *L, ErrMsg em);
|
||||
LJ_FUNC_NORET void lj_err_lex(lua_State *L, GCstr *src, const char *tok,
|
||||
BCLine line, ErrMsg em, va_list argp);
|
||||
LJ_FUNC_NORET void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm);
|
||||
LJ_FUNC_NORET void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2);
|
||||
LJ_FUNC_NORET void lj_err_optype_call(lua_State *L, TValue *o);
|
||||
LJ_FUNC_NORET void lj_err_callermsg(lua_State *L, const char *msg);
|
||||
LJ_FUNC_NORET void lj_err_callerv(lua_State *L, ErrMsg em, ...);
|
||||
LJ_FUNC_NORET void lj_err_caller(lua_State *L, ErrMsg em);
|
||||
LJ_FUNC_NORET void lj_err_arg(lua_State *L, int narg, ErrMsg em);
|
||||
LJ_FUNC_NORET void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...);
|
||||
LJ_FUNC_NORET void lj_err_argtype(lua_State *L, int narg, const char *xname);
|
||||
LJ_FUNC_NORET void lj_err_argt(lua_State *L, int narg, int tt);
|
||||
|
||||
#endif
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
** VM error messages.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* This file may be included multiple times with different ERRDEF macros. */
|
||||
|
||||
/* Basic error handling. */
|
||||
ERRDEF(ERRMEM, "not enough memory")
|
||||
ERRDEF(ERRERR, "error in error handling")
|
||||
ERRDEF(ERRCPP, "C++ exception")
|
||||
|
||||
/* Allocations. */
|
||||
ERRDEF(STROV, "string length overflow")
|
||||
ERRDEF(UDATAOV, "userdata length overflow")
|
||||
ERRDEF(STKOV, "stack overflow")
|
||||
ERRDEF(STKOVM, "stack overflow (%s)")
|
||||
ERRDEF(TABOV, "table overflow")
|
||||
|
||||
/* Table indexing. */
|
||||
ERRDEF(NANIDX, "table index is NaN")
|
||||
ERRDEF(NILIDX, "table index is nil")
|
||||
ERRDEF(NEXTIDX, "invalid key to " LUA_QL("next"))
|
||||
|
||||
/* Metamethod resolving. */
|
||||
ERRDEF(BADCALL, "attempt to call a %s value")
|
||||
ERRDEF(BADOPRT, "attempt to %s %s " LUA_QS " (a %s value)")
|
||||
ERRDEF(BADOPRV, "attempt to %s a %s value")
|
||||
ERRDEF(BADCMPT, "attempt to compare %s with %s")
|
||||
ERRDEF(BADCMPV, "attempt to compare two %s values")
|
||||
ERRDEF(GETLOOP, "loop in gettable")
|
||||
ERRDEF(SETLOOP, "loop in settable")
|
||||
ERRDEF(OPCALL, "call")
|
||||
ERRDEF(OPINDEX, "index")
|
||||
ERRDEF(OPARITH, "perform arithmetic on")
|
||||
ERRDEF(OPCAT, "concatenate")
|
||||
ERRDEF(OPLEN, "get length of")
|
||||
|
||||
/* Type checks. */
|
||||
ERRDEF(BADSELF, "calling " LUA_QS " on bad self (%s)")
|
||||
ERRDEF(BADARG, "bad argument #%d to " LUA_QS " (%s)")
|
||||
ERRDEF(BADTYPE, "%s expected, got %s")
|
||||
ERRDEF(BADVAL, "invalid value")
|
||||
ERRDEF(NOVAL, "value expected")
|
||||
ERRDEF(NOCORO, "coroutine expected")
|
||||
ERRDEF(NOTABN, "nil or table expected")
|
||||
ERRDEF(NOLFUNC, "Lua function expected")
|
||||
ERRDEF(NOFUNCL, "function or level expected")
|
||||
ERRDEF(NOSFT, "string/function/table expected")
|
||||
ERRDEF(NOPROXY, "boolean or proxy expected")
|
||||
ERRDEF(FORINIT, LUA_QL("for") " initial value must be a number")
|
||||
ERRDEF(FORLIM, LUA_QL("for") " limit must be a number")
|
||||
ERRDEF(FORSTEP, LUA_QL("for") " step must be a number")
|
||||
|
||||
/* C API checks. */
|
||||
ERRDEF(NOENV, "no calling environment")
|
||||
ERRDEF(CYIELD, "attempt to yield across C-call boundary")
|
||||
ERRDEF(BADLU, "bad light userdata pointer")
|
||||
ERRDEF(NOGCMM, "bad action while in __gc metamethod")
|
||||
#if LJ_TARGET_WINDOWS
|
||||
ERRDEF(BADFPU, "bad FPU precision (use D3DCREATE_FPU_PRESERVE with DirectX)")
|
||||
#endif
|
||||
|
||||
/* Standard library function errors. */
|
||||
ERRDEF(ASSERT, "assertion failed!")
|
||||
ERRDEF(PROTMT, "cannot change a protected metatable")
|
||||
ERRDEF(UNPACK, "too many results to unpack")
|
||||
ERRDEF(RDRSTR, "reader function must return a string")
|
||||
ERRDEF(PRTOSTR, LUA_QL("tostring") " must return a string to " LUA_QL("print"))
|
||||
ERRDEF(IDXRNG, "index out of range")
|
||||
ERRDEF(BASERNG, "base out of range")
|
||||
ERRDEF(LVLRNG, "level out of range")
|
||||
ERRDEF(INVLVL, "invalid level")
|
||||
ERRDEF(INVOPT, "invalid option")
|
||||
ERRDEF(INVOPTM, "invalid option " LUA_QS)
|
||||
ERRDEF(INVFMT, "invalid format")
|
||||
ERRDEF(SETFENV, LUA_QL("setfenv") " cannot change environment of given object")
|
||||
ERRDEF(CORUN, "cannot resume running coroutine")
|
||||
ERRDEF(CODEAD, "cannot resume dead coroutine")
|
||||
ERRDEF(COSUSP, "cannot resume non-suspended coroutine")
|
||||
ERRDEF(TABINS, "wrong number of arguments to " LUA_QL("insert"))
|
||||
ERRDEF(TABCAT, "invalid value (%s) at index %d in table for " LUA_QL("concat"))
|
||||
ERRDEF(TABSORT, "invalid order function for sorting")
|
||||
ERRDEF(IOCLFL, "attempt to use a closed file")
|
||||
ERRDEF(IOSTDCL, "standard file is closed")
|
||||
ERRDEF(OSUNIQF, "unable to generate a unique filename")
|
||||
ERRDEF(OSDATEF, "field " LUA_QS " missing in date table")
|
||||
ERRDEF(STRDUMP, "unable to dump given function")
|
||||
ERRDEF(STRSLC, "string slice too long")
|
||||
ERRDEF(STRPATB, "missing " LUA_QL("[") " after " LUA_QL("%f") " in pattern")
|
||||
ERRDEF(STRPATC, "invalid pattern capture")
|
||||
ERRDEF(STRPATE, "malformed pattern (ends with " LUA_QL("%") ")")
|
||||
ERRDEF(STRPATM, "malformed pattern (missing " LUA_QL("]") ")")
|
||||
ERRDEF(STRPATU, "unbalanced pattern")
|
||||
ERRDEF(STRPATX, "pattern too complex")
|
||||
ERRDEF(STRCAPI, "invalid capture index")
|
||||
ERRDEF(STRCAPN, "too many captures")
|
||||
ERRDEF(STRCAPU, "unfinished capture")
|
||||
ERRDEF(STRFMT, "invalid option " LUA_QS " to " LUA_QL("format"))
|
||||
ERRDEF(STRGSRV, "invalid replacement value (a %s)")
|
||||
ERRDEF(BADMODN, "name conflict for module " LUA_QS)
|
||||
#if LJ_HASJIT
|
||||
ERRDEF(JITPROT, "runtime code generation failed, restricted kernel?")
|
||||
#if LJ_TARGET_X86ORX64
|
||||
ERRDEF(NOJIT, "JIT compiler disabled, CPU does not support SSE2")
|
||||
#else
|
||||
ERRDEF(NOJIT, "JIT compiler disabled")
|
||||
#endif
|
||||
#elif defined(LJ_ARCH_NOJIT)
|
||||
ERRDEF(NOJIT, "no JIT compiler for this architecture (yet)")
|
||||
#else
|
||||
ERRDEF(NOJIT, "JIT compiler permanently disabled by build option")
|
||||
#endif
|
||||
ERRDEF(JITOPT, "unknown or malformed optimization flag " LUA_QS)
|
||||
|
||||
/* Lexer/parser errors. */
|
||||
ERRDEF(XMODE, "attempt to load chunk with wrong mode")
|
||||
ERRDEF(XNEAR, "%s near " LUA_QS)
|
||||
ERRDEF(XLINES, "chunk has too many lines")
|
||||
ERRDEF(XLEVELS, "chunk has too many syntax levels")
|
||||
ERRDEF(XNUMBER, "malformed number")
|
||||
ERRDEF(XLSTR, "unfinished long string")
|
||||
ERRDEF(XLCOM, "unfinished long comment")
|
||||
ERRDEF(XSTR, "unfinished string")
|
||||
ERRDEF(XESC, "invalid escape sequence")
|
||||
ERRDEF(XLDELIM, "invalid long string delimiter")
|
||||
ERRDEF(XTOKEN, LUA_QS " expected")
|
||||
ERRDEF(XJUMP, "control structure too long")
|
||||
ERRDEF(XSLOTS, "function or expression too complex")
|
||||
ERRDEF(XLIMC, "chunk has more than %d local variables")
|
||||
ERRDEF(XLIMM, "main function has more than %d %s")
|
||||
ERRDEF(XLIMF, "function at line %d has more than %d %s")
|
||||
ERRDEF(XMATCH, LUA_QS " expected (to close " LUA_QS " at line %d)")
|
||||
ERRDEF(XFIXUP, "function too long for return fixup")
|
||||
ERRDEF(XPARAM, "<name> or " LUA_QL("...") " expected")
|
||||
#if !LJ_52
|
||||
ERRDEF(XAMBIG, "ambiguous syntax (function call x new statement)")
|
||||
#endif
|
||||
ERRDEF(XFUNARG, "function arguments expected")
|
||||
ERRDEF(XSYMBOL, "unexpected symbol")
|
||||
ERRDEF(XDOTS, "cannot use " LUA_QL("...") " outside a vararg function")
|
||||
ERRDEF(XSYNTAX, "syntax error")
|
||||
ERRDEF(XFOR, LUA_QL("=") " or " LUA_QL("in") " expected")
|
||||
ERRDEF(XBREAK, "no loop to break")
|
||||
ERRDEF(XLUNDEF, "undefined label " LUA_QS)
|
||||
ERRDEF(XLDUP, "duplicate label " LUA_QS)
|
||||
ERRDEF(XGSCOPE, "<goto %s> jumps into the scope of local " LUA_QS)
|
||||
|
||||
/* Bytecode reader errors. */
|
||||
ERRDEF(BCFMT, "cannot load incompatible bytecode")
|
||||
ERRDEF(BCBAD, "cannot load malformed bytecode")
|
||||
|
||||
#if LJ_HASFFI
|
||||
/* FFI errors. */
|
||||
ERRDEF(FFI_INVTYPE, "invalid C type")
|
||||
ERRDEF(FFI_INVSIZE, "size of C type is unknown or too large")
|
||||
ERRDEF(FFI_BADSCL, "bad storage class")
|
||||
ERRDEF(FFI_DECLSPEC, "declaration specifier expected")
|
||||
ERRDEF(FFI_BADTAG, "undeclared or implicit tag " LUA_QS)
|
||||
ERRDEF(FFI_REDEF, "attempt to redefine " LUA_QS)
|
||||
ERRDEF(FFI_NUMPARAM, "wrong number of type parameters")
|
||||
ERRDEF(FFI_INITOV, "too many initializers for " LUA_QS)
|
||||
ERRDEF(FFI_BADCONV, "cannot convert " LUA_QS " to " LUA_QS)
|
||||
ERRDEF(FFI_BADLEN, "attempt to get length of " LUA_QS)
|
||||
ERRDEF(FFI_BADCONCAT, "attempt to concatenate " LUA_QS " and " LUA_QS)
|
||||
ERRDEF(FFI_BADARITH, "attempt to perform arithmetic on " LUA_QS " and " LUA_QS)
|
||||
ERRDEF(FFI_BADCOMP, "attempt to compare " LUA_QS " with " LUA_QS)
|
||||
ERRDEF(FFI_BADCALL, LUA_QS " is not callable")
|
||||
ERRDEF(FFI_NUMARG, "wrong number of arguments for function call")
|
||||
ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS)
|
||||
ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed")
|
||||
ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS)
|
||||
ERRDEF(FFI_BADMM, LUA_QS " has no " LUA_QS " metamethod")
|
||||
ERRDEF(FFI_WRCONST, "attempt to write to constant location")
|
||||
ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
|
||||
ERRDEF(FFI_BADCBACK, "bad callback")
|
||||
#if LJ_OS_NOJIT
|
||||
ERRDEF(FFI_CBACKOV, "no support for callbacks on this OS")
|
||||
#else
|
||||
ERRDEF(FFI_CBACKOV, "too many callbacks")
|
||||
#endif
|
||||
ERRDEF(FFI_NYIPACKBIT, "NYI: packed bit fields")
|
||||
ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)")
|
||||
#endif
|
||||
|
||||
#undef ERRDEF
|
||||
|
||||
/* Detecting unused error messages:
|
||||
awk -F, '/^ERRDEF/ { gsub(/ERRDEF./, ""); printf "grep -q LJ_ERR_%s *.[ch] || echo %s\n", $1, $1}' lj_errmsg.h | sh
|
||||
*/
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
** Fast function IDs.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_FF_H
|
||||
#define _LJ_FF_H
|
||||
|
||||
/* Fast function ID. */
|
||||
typedef enum {
|
||||
FF_LUA_ = FF_LUA, /* Lua function (must be 0). */
|
||||
FF_C_ = FF_C, /* Regular C function (must be 1). */
|
||||
#define FFDEF(name) FF_##name,
|
||||
#include "lj_ffdef.h"
|
||||
FF__MAX
|
||||
} FastFunc;
|
||||
|
||||
#endif
|
||||
@@ -1,210 +0,0 @@
|
||||
/* This is a generated file. DO NOT EDIT! */
|
||||
|
||||
FFDEF(assert)
|
||||
FFDEF(type)
|
||||
FFDEF(next)
|
||||
FFDEF(pairs)
|
||||
FFDEF(ipairs_aux)
|
||||
FFDEF(ipairs)
|
||||
FFDEF(getmetatable)
|
||||
FFDEF(setmetatable)
|
||||
FFDEF(getfenv)
|
||||
FFDEF(setfenv)
|
||||
FFDEF(rawget)
|
||||
FFDEF(rawset)
|
||||
FFDEF(rawequal)
|
||||
FFDEF(unpack)
|
||||
FFDEF(select)
|
||||
FFDEF(tonumber)
|
||||
FFDEF(tostring)
|
||||
FFDEF(error)
|
||||
FFDEF(pcall)
|
||||
FFDEF(xpcall)
|
||||
FFDEF(loadfile)
|
||||
FFDEF(load)
|
||||
FFDEF(loadstring)
|
||||
FFDEF(dofile)
|
||||
FFDEF(gcinfo)
|
||||
FFDEF(collectgarbage)
|
||||
FFDEF(newproxy)
|
||||
FFDEF(print)
|
||||
FFDEF(coroutine_status)
|
||||
FFDEF(coroutine_running)
|
||||
FFDEF(coroutine_isyieldable)
|
||||
FFDEF(coroutine_create)
|
||||
FFDEF(coroutine_yield)
|
||||
FFDEF(coroutine_resume)
|
||||
FFDEF(coroutine_wrap_aux)
|
||||
FFDEF(coroutine_wrap)
|
||||
FFDEF(math_abs)
|
||||
FFDEF(math_floor)
|
||||
FFDEF(math_ceil)
|
||||
FFDEF(math_sqrt)
|
||||
FFDEF(math_log10)
|
||||
FFDEF(math_exp)
|
||||
FFDEF(math_sin)
|
||||
FFDEF(math_cos)
|
||||
FFDEF(math_tan)
|
||||
FFDEF(math_asin)
|
||||
FFDEF(math_acos)
|
||||
FFDEF(math_atan)
|
||||
FFDEF(math_sinh)
|
||||
FFDEF(math_cosh)
|
||||
FFDEF(math_tanh)
|
||||
FFDEF(math_frexp)
|
||||
FFDEF(math_modf)
|
||||
FFDEF(math_log)
|
||||
FFDEF(math_atan2)
|
||||
FFDEF(math_pow)
|
||||
FFDEF(math_fmod)
|
||||
FFDEF(math_ldexp)
|
||||
FFDEF(math_min)
|
||||
FFDEF(math_max)
|
||||
FFDEF(math_random)
|
||||
FFDEF(math_randomseed)
|
||||
FFDEF(bit_tobit)
|
||||
FFDEF(bit_bnot)
|
||||
FFDEF(bit_bswap)
|
||||
FFDEF(bit_lshift)
|
||||
FFDEF(bit_rshift)
|
||||
FFDEF(bit_arshift)
|
||||
FFDEF(bit_rol)
|
||||
FFDEF(bit_ror)
|
||||
FFDEF(bit_band)
|
||||
FFDEF(bit_bor)
|
||||
FFDEF(bit_bxor)
|
||||
FFDEF(bit_tohex)
|
||||
FFDEF(string_byte)
|
||||
FFDEF(string_char)
|
||||
FFDEF(string_sub)
|
||||
FFDEF(string_rep)
|
||||
FFDEF(string_reverse)
|
||||
FFDEF(string_lower)
|
||||
FFDEF(string_upper)
|
||||
FFDEF(string_dump)
|
||||
FFDEF(string_find)
|
||||
FFDEF(string_match)
|
||||
FFDEF(string_gmatch_aux)
|
||||
FFDEF(string_gmatch)
|
||||
FFDEF(string_gsub)
|
||||
FFDEF(string_format)
|
||||
FFDEF(table_maxn)
|
||||
FFDEF(table_insert)
|
||||
FFDEF(table_concat)
|
||||
FFDEF(table_sort)
|
||||
FFDEF(table_new)
|
||||
FFDEF(table_clear)
|
||||
FFDEF(io_method_close)
|
||||
FFDEF(io_method_read)
|
||||
FFDEF(io_method_write)
|
||||
FFDEF(io_method_flush)
|
||||
FFDEF(io_method_seek)
|
||||
FFDEF(io_method_setvbuf)
|
||||
FFDEF(io_method_lines)
|
||||
FFDEF(io_method___gc)
|
||||
FFDEF(io_method___tostring)
|
||||
FFDEF(io_open)
|
||||
FFDEF(io_popen)
|
||||
FFDEF(io_tmpfile)
|
||||
FFDEF(io_close)
|
||||
FFDEF(io_read)
|
||||
FFDEF(io_write)
|
||||
FFDEF(io_flush)
|
||||
FFDEF(io_input)
|
||||
FFDEF(io_output)
|
||||
FFDEF(io_lines)
|
||||
FFDEF(io_type)
|
||||
FFDEF(os_execute)
|
||||
FFDEF(os_remove)
|
||||
FFDEF(os_rename)
|
||||
FFDEF(os_tmpname)
|
||||
FFDEF(os_getenv)
|
||||
FFDEF(os_exit)
|
||||
FFDEF(os_clock)
|
||||
FFDEF(os_date)
|
||||
FFDEF(os_time)
|
||||
FFDEF(os_difftime)
|
||||
FFDEF(os_setlocale)
|
||||
FFDEF(debug_getregistry)
|
||||
FFDEF(debug_getmetatable)
|
||||
FFDEF(debug_setmetatable)
|
||||
FFDEF(debug_getfenv)
|
||||
FFDEF(debug_setfenv)
|
||||
FFDEF(debug_getinfo)
|
||||
FFDEF(debug_getlocal)
|
||||
FFDEF(debug_setlocal)
|
||||
FFDEF(debug_getupvalue)
|
||||
FFDEF(debug_setupvalue)
|
||||
FFDEF(debug_upvalueid)
|
||||
FFDEF(debug_upvaluejoin)
|
||||
FFDEF(debug_sethook)
|
||||
FFDEF(debug_gethook)
|
||||
FFDEF(debug_debug)
|
||||
FFDEF(debug_traceback)
|
||||
FFDEF(jit_on)
|
||||
FFDEF(jit_off)
|
||||
FFDEF(jit_flush)
|
||||
FFDEF(jit_status)
|
||||
FFDEF(jit_attach)
|
||||
FFDEF(jit_util_funcinfo)
|
||||
FFDEF(jit_util_funcbc)
|
||||
FFDEF(jit_util_funck)
|
||||
FFDEF(jit_util_funcuvname)
|
||||
FFDEF(jit_util_traceinfo)
|
||||
FFDEF(jit_util_traceir)
|
||||
FFDEF(jit_util_tracek)
|
||||
FFDEF(jit_util_tracesnap)
|
||||
FFDEF(jit_util_tracemc)
|
||||
FFDEF(jit_util_traceexitstub)
|
||||
FFDEF(jit_util_ircalladdr)
|
||||
FFDEF(jit_opt_start)
|
||||
FFDEF(jit_profile_start)
|
||||
FFDEF(jit_profile_stop)
|
||||
FFDEF(jit_profile_dumpstack)
|
||||
FFDEF(ffi_meta___index)
|
||||
FFDEF(ffi_meta___newindex)
|
||||
FFDEF(ffi_meta___eq)
|
||||
FFDEF(ffi_meta___len)
|
||||
FFDEF(ffi_meta___lt)
|
||||
FFDEF(ffi_meta___le)
|
||||
FFDEF(ffi_meta___concat)
|
||||
FFDEF(ffi_meta___call)
|
||||
FFDEF(ffi_meta___add)
|
||||
FFDEF(ffi_meta___sub)
|
||||
FFDEF(ffi_meta___mul)
|
||||
FFDEF(ffi_meta___div)
|
||||
FFDEF(ffi_meta___mod)
|
||||
FFDEF(ffi_meta___pow)
|
||||
FFDEF(ffi_meta___unm)
|
||||
FFDEF(ffi_meta___tostring)
|
||||
FFDEF(ffi_meta___pairs)
|
||||
FFDEF(ffi_meta___ipairs)
|
||||
FFDEF(ffi_clib___index)
|
||||
FFDEF(ffi_clib___newindex)
|
||||
FFDEF(ffi_clib___gc)
|
||||
FFDEF(ffi_callback_free)
|
||||
FFDEF(ffi_callback_set)
|
||||
FFDEF(ffi_cdef)
|
||||
FFDEF(ffi_new)
|
||||
FFDEF(ffi_cast)
|
||||
FFDEF(ffi_typeof)
|
||||
FFDEF(ffi_typeinfo)
|
||||
FFDEF(ffi_istype)
|
||||
FFDEF(ffi_sizeof)
|
||||
FFDEF(ffi_alignof)
|
||||
FFDEF(ffi_offsetof)
|
||||
FFDEF(ffi_errno)
|
||||
FFDEF(ffi_string)
|
||||
FFDEF(ffi_copy)
|
||||
FFDEF(ffi_fill)
|
||||
FFDEF(ffi_abi)
|
||||
FFDEF(ffi_metatype)
|
||||
FFDEF(ffi_gc)
|
||||
FFDEF(ffi_load)
|
||||
|
||||
#undef FFDEF
|
||||
|
||||
#ifndef FF_NUM_ASMFUNC
|
||||
#define FF_NUM_ASMFUNC 57
|
||||
#endif
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
** Fast function call recorder.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_FFRECORD_H
|
||||
#define _LJ_FFRECORD_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_jit.h"
|
||||
|
||||
#if LJ_HASJIT
|
||||
/* Data used by handlers to record a fast function. */
|
||||
typedef struct RecordFFData {
|
||||
TValue *argv; /* Runtime argument values. */
|
||||
ptrdiff_t nres; /* Number of returned results (defaults to 1). */
|
||||
uint32_t data; /* Per-ffid auxiliary data (opcode, literal etc.). */
|
||||
} RecordFFData;
|
||||
|
||||
LJ_FUNC int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv);
|
||||
LJ_FUNC void lj_ffrecord_func(jit_State *J);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,297 +0,0 @@
|
||||
/*
|
||||
** Stack frames.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_FRAME_H
|
||||
#define _LJ_FRAME_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_bc.h"
|
||||
|
||||
/* -- Lua stack frame ----------------------------------------------------- */
|
||||
|
||||
/* Frame type markers in LSB of PC (4-byte aligned) or delta (8-byte aligned:
|
||||
**
|
||||
** PC 00 Lua frame
|
||||
** delta 001 C frame
|
||||
** delta 010 Continuation frame
|
||||
** delta 011 Lua vararg frame
|
||||
** delta 101 cpcall() frame
|
||||
** delta 110 ff pcall() frame
|
||||
** delta 111 ff pcall() frame with active hook
|
||||
*/
|
||||
enum {
|
||||
FRAME_LUA, FRAME_C, FRAME_CONT, FRAME_VARG,
|
||||
FRAME_LUAP, FRAME_CP, FRAME_PCALL, FRAME_PCALLH
|
||||
};
|
||||
#define FRAME_TYPE 3
|
||||
#define FRAME_P 4
|
||||
#define FRAME_TYPEP (FRAME_TYPE|FRAME_P)
|
||||
|
||||
/* Macros to access and modify Lua frames. */
|
||||
#if LJ_FR2
|
||||
/* Two-slot frame info, required for 64 bit PC/GCRef:
|
||||
**
|
||||
** base-2 base-1 | base base+1 ...
|
||||
** [func PC/delta/ft] | [slots ...]
|
||||
** ^-- frame | ^-- base ^-- top
|
||||
**
|
||||
** Continuation frames:
|
||||
**
|
||||
** base-4 base-3 base-2 base-1 | base base+1 ...
|
||||
** [cont PC ] [func PC/delta/ft] | [slots ...]
|
||||
** ^-- frame | ^-- base ^-- top
|
||||
*/
|
||||
#define frame_gc(f) (gcval((f)-1))
|
||||
#define frame_ftsz(f) ((ptrdiff_t)(f)->ftsz)
|
||||
#define frame_pc(f) ((const BCIns *)frame_ftsz(f))
|
||||
#define setframe_gc(f, p, tp) (setgcVraw((f)-1, (p), (tp)))
|
||||
#define setframe_ftsz(f, sz) ((f)->ftsz = (sz))
|
||||
#define setframe_pc(f, pc) ((f)->ftsz = (int64_t)(intptr_t)(pc))
|
||||
#else
|
||||
/* One-slot frame info, sufficient for 32 bit PC/GCRef:
|
||||
**
|
||||
** base-1 | base base+1 ...
|
||||
** lo hi |
|
||||
** [func | PC/delta/ft] | [slots ...]
|
||||
** ^-- frame | ^-- base ^-- top
|
||||
**
|
||||
** Continuation frames:
|
||||
**
|
||||
** base-2 base-1 | base base+1 ...
|
||||
** lo hi lo hi |
|
||||
** [cont | PC] [func | PC/delta/ft] | [slots ...]
|
||||
** ^-- frame | ^-- base ^-- top
|
||||
*/
|
||||
#define frame_gc(f) (gcref((f)->fr.func))
|
||||
#define frame_ftsz(f) ((ptrdiff_t)(f)->fr.tp.ftsz)
|
||||
#define frame_pc(f) (mref((f)->fr.tp.pcr, const BCIns))
|
||||
#define setframe_gc(f, p, tp) (setgcref((f)->fr.func, (p)), UNUSED(tp))
|
||||
#define setframe_ftsz(f, sz) ((f)->fr.tp.ftsz = (int32_t)(sz))
|
||||
#define setframe_pc(f, pc) (setmref((f)->fr.tp.pcr, (pc)))
|
||||
#endif
|
||||
|
||||
#define frame_type(f) (frame_ftsz(f) & FRAME_TYPE)
|
||||
#define frame_typep(f) (frame_ftsz(f) & FRAME_TYPEP)
|
||||
#define frame_islua(f) (frame_type(f) == FRAME_LUA)
|
||||
#define frame_isc(f) (frame_type(f) == FRAME_C)
|
||||
#define frame_iscont(f) (frame_typep(f) == FRAME_CONT)
|
||||
#define frame_isvarg(f) (frame_typep(f) == FRAME_VARG)
|
||||
#define frame_ispcall(f) ((frame_ftsz(f) & 6) == FRAME_PCALL)
|
||||
|
||||
#define frame_func(f) (&frame_gc(f)->fn)
|
||||
#define frame_delta(f) (frame_ftsz(f) >> 3)
|
||||
#define frame_sized(f) (frame_ftsz(f) & ~FRAME_TYPEP)
|
||||
|
||||
enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */
|
||||
|
||||
#if LJ_FR2
|
||||
#define frame_contpc(f) (frame_pc((f)-2))
|
||||
#define frame_contv(f) (((f)-3)->u64)
|
||||
#else
|
||||
#define frame_contpc(f) (frame_pc((f)-1))
|
||||
#define frame_contv(f) (((f)-1)->u32.lo)
|
||||
#endif
|
||||
#if LJ_FR2
|
||||
#define frame_contf(f) ((ASMFunction)(uintptr_t)((f)-3)->u64)
|
||||
#elif LJ_64
|
||||
#define frame_contf(f) \
|
||||
((ASMFunction)(void *)((intptr_t)lj_vm_asm_begin + \
|
||||
(intptr_t)(int32_t)((f)-1)->u32.lo))
|
||||
#else
|
||||
#define frame_contf(f) ((ASMFunction)gcrefp(((f)-1)->gcr, void))
|
||||
#endif
|
||||
#define frame_iscont_fficb(f) \
|
||||
(LJ_HASFFI && frame_contv(f) == LJ_CONT_FFI_CALLBACK)
|
||||
|
||||
#define frame_prevl(f) ((f) - (1+LJ_FR2+bc_a(frame_pc(f)[-1])))
|
||||
#define frame_prevd(f) ((TValue *)((char *)(f) - frame_sized(f)))
|
||||
#define frame_prev(f) (frame_islua(f)?frame_prevl(f):frame_prevd(f))
|
||||
/* Note: this macro does not skip over FRAME_VARG. */
|
||||
|
||||
/* -- C stack frame ------------------------------------------------------- */
|
||||
|
||||
/* Macros to access and modify the C stack frame chain. */
|
||||
|
||||
/* These definitions must match with the arch-specific *.dasc files. */
|
||||
#if LJ_TARGET_X86
|
||||
#if LJ_ABI_WIN
|
||||
#define CFRAME_OFS_ERRF (19*4)
|
||||
#define CFRAME_OFS_NRES (18*4)
|
||||
#define CFRAME_OFS_PREV (17*4)
|
||||
#define CFRAME_OFS_L (16*4)
|
||||
#define CFRAME_OFS_SEH (9*4)
|
||||
#define CFRAME_OFS_PC (6*4)
|
||||
#define CFRAME_OFS_MULTRES (5*4)
|
||||
#define CFRAME_SIZE (16*4)
|
||||
#define CFRAME_SHIFT_MULTRES 0
|
||||
#else
|
||||
#define CFRAME_OFS_ERRF (15*4)
|
||||
#define CFRAME_OFS_NRES (14*4)
|
||||
#define CFRAME_OFS_PREV (13*4)
|
||||
#define CFRAME_OFS_L (12*4)
|
||||
#define CFRAME_OFS_PC (6*4)
|
||||
#define CFRAME_OFS_MULTRES (5*4)
|
||||
#define CFRAME_SIZE (12*4)
|
||||
#define CFRAME_SHIFT_MULTRES 0
|
||||
#endif
|
||||
#elif LJ_TARGET_X64
|
||||
#if LJ_ABI_WIN
|
||||
#define CFRAME_OFS_PREV (13*8)
|
||||
#if LJ_GC64
|
||||
#define CFRAME_OFS_PC (12*8)
|
||||
#define CFRAME_OFS_L (11*8)
|
||||
#define CFRAME_OFS_ERRF (21*4)
|
||||
#define CFRAME_OFS_NRES (20*4)
|
||||
#define CFRAME_OFS_MULTRES (8*4)
|
||||
#else
|
||||
#define CFRAME_OFS_PC (25*4)
|
||||
#define CFRAME_OFS_L (24*4)
|
||||
#define CFRAME_OFS_ERRF (23*4)
|
||||
#define CFRAME_OFS_NRES (22*4)
|
||||
#define CFRAME_OFS_MULTRES (21*4)
|
||||
#endif
|
||||
#define CFRAME_SIZE (10*8)
|
||||
#define CFRAME_SIZE_JIT (CFRAME_SIZE + 9*16 + 4*8)
|
||||
#define CFRAME_SHIFT_MULTRES 0
|
||||
#else
|
||||
#define CFRAME_OFS_PREV (4*8)
|
||||
#if LJ_GC64
|
||||
#define CFRAME_OFS_PC (3*8)
|
||||
#define CFRAME_OFS_L (2*8)
|
||||
#define CFRAME_OFS_ERRF (3*4)
|
||||
#define CFRAME_OFS_NRES (2*4)
|
||||
#define CFRAME_OFS_MULTRES (0*4)
|
||||
#else
|
||||
#define CFRAME_OFS_PC (7*4)
|
||||
#define CFRAME_OFS_L (6*4)
|
||||
#define CFRAME_OFS_ERRF (5*4)
|
||||
#define CFRAME_OFS_NRES (4*4)
|
||||
#define CFRAME_OFS_MULTRES (1*4)
|
||||
#endif
|
||||
#if LJ_NO_UNWIND
|
||||
#define CFRAME_SIZE (12*8)
|
||||
#else
|
||||
#define CFRAME_SIZE (10*8)
|
||||
#endif
|
||||
#define CFRAME_SIZE_JIT (CFRAME_SIZE + 16)
|
||||
#define CFRAME_SHIFT_MULTRES 0
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM
|
||||
#define CFRAME_OFS_ERRF 24
|
||||
#define CFRAME_OFS_NRES 20
|
||||
#define CFRAME_OFS_PREV 16
|
||||
#define CFRAME_OFS_L 12
|
||||
#define CFRAME_OFS_PC 8
|
||||
#define CFRAME_OFS_MULTRES 4
|
||||
#if LJ_ARCH_HASFPU
|
||||
#define CFRAME_SIZE 128
|
||||
#else
|
||||
#define CFRAME_SIZE 64
|
||||
#endif
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#elif LJ_TARGET_ARM64
|
||||
#define CFRAME_OFS_ERRF 196
|
||||
#define CFRAME_OFS_NRES 200
|
||||
#define CFRAME_OFS_PREV 160
|
||||
#define CFRAME_OFS_L 176
|
||||
#define CFRAME_OFS_PC 168
|
||||
#define CFRAME_OFS_MULTRES 192
|
||||
#define CFRAME_SIZE 208
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#elif LJ_TARGET_PPC
|
||||
#if LJ_TARGET_XBOX360
|
||||
#define CFRAME_OFS_ERRF 424
|
||||
#define CFRAME_OFS_NRES 420
|
||||
#define CFRAME_OFS_PREV 400
|
||||
#define CFRAME_OFS_L 416
|
||||
#define CFRAME_OFS_PC 412
|
||||
#define CFRAME_OFS_MULTRES 408
|
||||
#define CFRAME_SIZE 384
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#elif LJ_ARCH_PPC32ON64
|
||||
#define CFRAME_OFS_ERRF 472
|
||||
#define CFRAME_OFS_NRES 468
|
||||
#define CFRAME_OFS_PREV 448
|
||||
#define CFRAME_OFS_L 464
|
||||
#define CFRAME_OFS_PC 460
|
||||
#define CFRAME_OFS_MULTRES 456
|
||||
#define CFRAME_SIZE 400
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#else
|
||||
#define CFRAME_OFS_ERRF 48
|
||||
#define CFRAME_OFS_NRES 44
|
||||
#define CFRAME_OFS_PREV 40
|
||||
#define CFRAME_OFS_L 36
|
||||
#define CFRAME_OFS_PC 32
|
||||
#define CFRAME_OFS_MULTRES 28
|
||||
#define CFRAME_SIZE 272
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS32
|
||||
#if LJ_ARCH_HASFPU
|
||||
#define CFRAME_OFS_ERRF 124
|
||||
#define CFRAME_OFS_NRES 120
|
||||
#define CFRAME_OFS_PREV 116
|
||||
#define CFRAME_OFS_L 112
|
||||
#define CFRAME_SIZE 112
|
||||
#else
|
||||
#define CFRAME_OFS_ERRF 76
|
||||
#define CFRAME_OFS_NRES 72
|
||||
#define CFRAME_OFS_PREV 68
|
||||
#define CFRAME_OFS_L 64
|
||||
#define CFRAME_SIZE 64
|
||||
#endif
|
||||
#define CFRAME_OFS_PC 20
|
||||
#define CFRAME_OFS_MULTRES 16
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#elif LJ_TARGET_MIPS64
|
||||
#if LJ_ARCH_HASFPU
|
||||
#define CFRAME_OFS_ERRF 188
|
||||
#define CFRAME_OFS_NRES 184
|
||||
#define CFRAME_OFS_PREV 176
|
||||
#define CFRAME_OFS_L 168
|
||||
#define CFRAME_OFS_PC 160
|
||||
#define CFRAME_SIZE 192
|
||||
#else
|
||||
#define CFRAME_OFS_ERRF 124
|
||||
#define CFRAME_OFS_NRES 120
|
||||
#define CFRAME_OFS_PREV 112
|
||||
#define CFRAME_OFS_L 104
|
||||
#define CFRAME_OFS_PC 96
|
||||
#define CFRAME_SIZE 128
|
||||
#endif
|
||||
#define CFRAME_OFS_MULTRES 0
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#else
|
||||
#error "Missing CFRAME_* definitions for this architecture"
|
||||
#endif
|
||||
|
||||
#ifndef CFRAME_SIZE_JIT
|
||||
#define CFRAME_SIZE_JIT CFRAME_SIZE
|
||||
#endif
|
||||
|
||||
#define CFRAME_RESUME 1
|
||||
#define CFRAME_UNWIND_FF 2 /* Only used in unwinder. */
|
||||
#define CFRAME_RAWMASK (~(intptr_t)(CFRAME_RESUME|CFRAME_UNWIND_FF))
|
||||
|
||||
#define cframe_errfunc(cf) (*(int32_t *)(((char *)(cf))+CFRAME_OFS_ERRF))
|
||||
#define cframe_nres(cf) (*(int32_t *)(((char *)(cf))+CFRAME_OFS_NRES))
|
||||
#define cframe_prev(cf) (*(void **)(((char *)(cf))+CFRAME_OFS_PREV))
|
||||
#define cframe_multres(cf) (*(uint32_t *)(((char *)(cf))+CFRAME_OFS_MULTRES))
|
||||
#define cframe_multres_n(cf) (cframe_multres((cf)) >> CFRAME_SHIFT_MULTRES)
|
||||
#define cframe_L(cf) \
|
||||
(&gcref(*(GCRef *)(((char *)(cf))+CFRAME_OFS_L))->th)
|
||||
#define cframe_pc(cf) \
|
||||
(mref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), const BCIns))
|
||||
#define setcframe_L(cf, L) \
|
||||
(setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_L), (L)))
|
||||
#define setcframe_pc(cf, pc) \
|
||||
(setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), (pc)))
|
||||
#define cframe_canyield(cf) ((intptr_t)(cf) & CFRAME_RESUME)
|
||||
#define cframe_unwind_ff(cf) ((intptr_t)(cf) & CFRAME_UNWIND_FF)
|
||||
#define cframe_raw(cf) ((void *)((intptr_t)(cf) & CFRAME_RAWMASK))
|
||||
#define cframe_Lpc(L) cframe_pc(cframe_raw(L->cframe))
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
** Function handling (prototypes, functions and upvalues).
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_FUNC_H
|
||||
#define _LJ_FUNC_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* Prototypes. */
|
||||
LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt);
|
||||
|
||||
/* Upvalues. */
|
||||
LJ_FUNCA void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level);
|
||||
LJ_FUNC void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv);
|
||||
|
||||
/* Functions (closures). */
|
||||
LJ_FUNC GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env);
|
||||
LJ_FUNC GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env);
|
||||
LJ_FUNCA GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent);
|
||||
LJ_FUNC void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *c);
|
||||
|
||||
#endif
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
** Garbage collector.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_GC_H
|
||||
#define _LJ_GC_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* Garbage collector states. Order matters. */
|
||||
enum {
|
||||
GCSpause, GCSpropagate, GCSatomic, GCSsweepstring, GCSsweep, GCSfinalize
|
||||
};
|
||||
|
||||
/* Bitmasks for marked field of GCobj. */
|
||||
#define LJ_GC_WHITE0 0x01
|
||||
#define LJ_GC_WHITE1 0x02
|
||||
#define LJ_GC_BLACK 0x04
|
||||
#define LJ_GC_FINALIZED 0x08
|
||||
#define LJ_GC_WEAKKEY 0x08
|
||||
#define LJ_GC_WEAKVAL 0x10
|
||||
#define LJ_GC_CDATA_FIN 0x10
|
||||
#define LJ_GC_FIXED 0x20
|
||||
#define LJ_GC_SFIXED 0x40
|
||||
|
||||
#define LJ_GC_WHITES (LJ_GC_WHITE0 | LJ_GC_WHITE1)
|
||||
#define LJ_GC_COLORS (LJ_GC_WHITES | LJ_GC_BLACK)
|
||||
#define LJ_GC_WEAK (LJ_GC_WEAKKEY | LJ_GC_WEAKVAL)
|
||||
|
||||
/* Macros to test and set GCobj colors. */
|
||||
#define iswhite(x) ((x)->gch.marked & LJ_GC_WHITES)
|
||||
#define isblack(x) ((x)->gch.marked & LJ_GC_BLACK)
|
||||
#define isgray(x) (!((x)->gch.marked & (LJ_GC_BLACK|LJ_GC_WHITES)))
|
||||
#define tviswhite(x) (tvisgcv(x) && iswhite(gcV(x)))
|
||||
#define otherwhite(g) (g->gc.currentwhite ^ LJ_GC_WHITES)
|
||||
#define isdead(g, v) ((v)->gch.marked & otherwhite(g) & LJ_GC_WHITES)
|
||||
|
||||
#define curwhite(g) ((g)->gc.currentwhite & LJ_GC_WHITES)
|
||||
#define newwhite(g, x) (obj2gco(x)->gch.marked = (uint8_t)curwhite(g))
|
||||
#define makewhite(g, x) \
|
||||
((x)->gch.marked = ((x)->gch.marked & (uint8_t)~LJ_GC_COLORS) | curwhite(g))
|
||||
#define flipwhite(x) ((x)->gch.marked ^= LJ_GC_WHITES)
|
||||
#define black2gray(x) ((x)->gch.marked &= (uint8_t)~LJ_GC_BLACK)
|
||||
#define fixstring(s) ((s)->marked |= LJ_GC_FIXED)
|
||||
#define markfinalized(x) ((x)->gch.marked |= LJ_GC_FINALIZED)
|
||||
|
||||
/* Collector. */
|
||||
LJ_FUNC size_t lj_gc_separateudata(global_State *g, int all);
|
||||
LJ_FUNC void lj_gc_finalize_udata(lua_State *L);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC void lj_gc_finalize_cdata(lua_State *L);
|
||||
#else
|
||||
#define lj_gc_finalize_cdata(L) UNUSED(L)
|
||||
#endif
|
||||
LJ_FUNC void lj_gc_freeall(global_State *g);
|
||||
LJ_FUNCA int LJ_FASTCALL lj_gc_step(lua_State *L);
|
||||
LJ_FUNCA void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps);
|
||||
#endif
|
||||
LJ_FUNC void lj_gc_fullgc(lua_State *L);
|
||||
|
||||
/* GC check: drive collector forward if the GC threshold has been reached. */
|
||||
#define lj_gc_check(L) \
|
||||
{ if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
|
||||
lj_gc_step(L); }
|
||||
#define lj_gc_check_fixtop(L) \
|
||||
{ if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
|
||||
lj_gc_step_fixtop(L); }
|
||||
|
||||
/* Write barriers. */
|
||||
LJ_FUNC void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v);
|
||||
LJ_FUNCA void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv);
|
||||
LJ_FUNC void lj_gc_closeuv(global_State *g, GCupval *uv);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC void lj_gc_barriertrace(global_State *g, uint32_t traceno);
|
||||
#endif
|
||||
|
||||
/* Move the GC propagation frontier back for tables (make it gray again). */
|
||||
static LJ_AINLINE void lj_gc_barrierback(global_State *g, GCtab *t)
|
||||
{
|
||||
GCobj *o = obj2gco(t);
|
||||
lua_assert(isblack(o) && !isdead(g, o));
|
||||
lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
|
||||
black2gray(o);
|
||||
setgcrefr(t->gclist, g->gc.grayagain);
|
||||
setgcref(g->gc.grayagain, o);
|
||||
}
|
||||
|
||||
/* Barrier for stores to table objects. TValue and GCobj variant. */
|
||||
#define lj_gc_anybarriert(L, t) \
|
||||
{ if (LJ_UNLIKELY(isblack(obj2gco(t)))) lj_gc_barrierback(G(L), (t)); }
|
||||
#define lj_gc_barriert(L, t, tv) \
|
||||
{ if (tviswhite(tv) && isblack(obj2gco(t))) \
|
||||
lj_gc_barrierback(G(L), (t)); }
|
||||
#define lj_gc_objbarriert(L, t, o) \
|
||||
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) \
|
||||
lj_gc_barrierback(G(L), (t)); }
|
||||
|
||||
/* Barrier for stores to any other object. TValue and GCobj variant. */
|
||||
#define lj_gc_barrier(L, p, tv) \
|
||||
{ if (tviswhite(tv) && isblack(obj2gco(p))) \
|
||||
lj_gc_barrierf(G(L), obj2gco(p), gcV(tv)); }
|
||||
#define lj_gc_objbarrier(L, p, o) \
|
||||
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
|
||||
lj_gc_barrierf(G(L), obj2gco(p), obj2gco(o)); }
|
||||
|
||||
/* Allocator. */
|
||||
LJ_FUNC void *lj_mem_realloc(lua_State *L, void *p, GCSize osz, GCSize nsz);
|
||||
LJ_FUNC void * LJ_FASTCALL lj_mem_newgco(lua_State *L, GCSize size);
|
||||
LJ_FUNC void *lj_mem_grow(lua_State *L, void *p,
|
||||
MSize *szp, MSize lim, MSize esz);
|
||||
|
||||
#define lj_mem_new(L, s) lj_mem_realloc(L, NULL, 0, (s))
|
||||
|
||||
static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize)
|
||||
{
|
||||
g->gc.total -= (GCSize)osize;
|
||||
g->allocf(g->allocd, p, osize, 0);
|
||||
}
|
||||
|
||||
#define lj_mem_newvec(L, n, t) ((t *)lj_mem_new(L, (GCSize)((n)*sizeof(t))))
|
||||
#define lj_mem_reallocvec(L, p, on, n, t) \
|
||||
((p) = (t *)lj_mem_realloc(L, p, (on)*sizeof(t), (GCSize)((n)*sizeof(t))))
|
||||
#define lj_mem_growvec(L, p, n, m, t) \
|
||||
((p) = (t *)lj_mem_grow(L, (p), &(n), (m), (MSize)sizeof(t)))
|
||||
#define lj_mem_freevec(g, p, n, t) lj_mem_free(g, (p), (n)*sizeof(t))
|
||||
|
||||
#define lj_mem_newobj(L, t) ((t *)lj_mem_newgco(L, sizeof(t)))
|
||||
#define lj_mem_newt(L, s, t) ((t *)lj_mem_new(L, (s)))
|
||||
#define lj_mem_freet(g, p) lj_mem_free(g, (p), sizeof(*(p)))
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
** Client for the GDB JIT API.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_GDBJIT_H
|
||||
#define _LJ_GDBJIT_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_jit.h"
|
||||
|
||||
#if LJ_HASJIT && defined(LUAJIT_USE_GDBJIT)
|
||||
|
||||
LJ_FUNC void lj_gdbjit_addtrace(jit_State *J, GCtrace *T);
|
||||
LJ_FUNC void lj_gdbjit_deltrace(jit_State *J, GCtrace *T);
|
||||
|
||||
#else
|
||||
#define lj_gdbjit_addtrace(J, T) UNUSED(T)
|
||||
#define lj_gdbjit_deltrace(J, T) UNUSED(T)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,588 +0,0 @@
|
||||
/*
|
||||
** SSA IR (Intermediate Representation) format.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_IR_H
|
||||
#define _LJ_IR_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* -- IR instructions ----------------------------------------------------- */
|
||||
|
||||
/* IR instruction definition. Order matters, see below. ORDER IR */
|
||||
#define IRDEF(_) \
|
||||
/* Guarded assertions. */ \
|
||||
/* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \
|
||||
_(LT, N , ref, ref) \
|
||||
_(GE, N , ref, ref) \
|
||||
_(LE, N , ref, ref) \
|
||||
_(GT, N , ref, ref) \
|
||||
\
|
||||
_(ULT, N , ref, ref) \
|
||||
_(UGE, N , ref, ref) \
|
||||
_(ULE, N , ref, ref) \
|
||||
_(UGT, N , ref, ref) \
|
||||
\
|
||||
_(EQ, C , ref, ref) \
|
||||
_(NE, C , ref, ref) \
|
||||
\
|
||||
_(ABC, N , ref, ref) \
|
||||
_(RETF, S , ref, ref) \
|
||||
\
|
||||
/* Miscellaneous ops. */ \
|
||||
_(NOP, N , ___, ___) \
|
||||
_(BASE, N , lit, lit) \
|
||||
_(PVAL, N , lit, ___) \
|
||||
_(GCSTEP, S , ___, ___) \
|
||||
_(HIOP, S , ref, ref) \
|
||||
_(LOOP, S , ___, ___) \
|
||||
_(USE, S , ref, ___) \
|
||||
_(PHI, S , ref, ref) \
|
||||
_(RENAME, S , ref, lit) \
|
||||
_(PROF, S , ___, ___) \
|
||||
\
|
||||
/* Constants. */ \
|
||||
_(KPRI, N , ___, ___) \
|
||||
_(KINT, N , cst, ___) \
|
||||
_(KGC, N , cst, ___) \
|
||||
_(KPTR, N , cst, ___) \
|
||||
_(KKPTR, N , cst, ___) \
|
||||
_(KNULL, N , cst, ___) \
|
||||
_(KNUM, N , cst, ___) \
|
||||
_(KINT64, N , cst, ___) \
|
||||
_(KSLOT, N , ref, lit) \
|
||||
\
|
||||
/* Bit ops. */ \
|
||||
_(BNOT, N , ref, ___) \
|
||||
_(BSWAP, N , ref, ___) \
|
||||
_(BAND, C , ref, ref) \
|
||||
_(BOR, C , ref, ref) \
|
||||
_(BXOR, C , ref, ref) \
|
||||
_(BSHL, N , ref, ref) \
|
||||
_(BSHR, N , ref, ref) \
|
||||
_(BSAR, N , ref, ref) \
|
||||
_(BROL, N , ref, ref) \
|
||||
_(BROR, N , ref, ref) \
|
||||
\
|
||||
/* Arithmetic ops. ORDER ARITH */ \
|
||||
_(ADD, C , ref, ref) \
|
||||
_(SUB, N , ref, ref) \
|
||||
_(MUL, C , ref, ref) \
|
||||
_(DIV, N , ref, ref) \
|
||||
_(MOD, N , ref, ref) \
|
||||
_(POW, N , ref, ref) \
|
||||
_(NEG, N , ref, ref) \
|
||||
\
|
||||
_(ABS, N , ref, ref) \
|
||||
_(ATAN2, N , ref, ref) \
|
||||
_(LDEXP, N , ref, ref) \
|
||||
_(MIN, C , ref, ref) \
|
||||
_(MAX, C , ref, ref) \
|
||||
_(FPMATH, N , ref, lit) \
|
||||
\
|
||||
/* Overflow-checking arithmetic ops. */ \
|
||||
_(ADDOV, CW, ref, ref) \
|
||||
_(SUBOV, NW, ref, ref) \
|
||||
_(MULOV, CW, ref, ref) \
|
||||
\
|
||||
/* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \
|
||||
\
|
||||
/* Memory references. */ \
|
||||
_(AREF, R , ref, ref) \
|
||||
_(HREFK, R , ref, ref) \
|
||||
_(HREF, L , ref, ref) \
|
||||
_(NEWREF, S , ref, ref) \
|
||||
_(UREFO, LW, ref, lit) \
|
||||
_(UREFC, LW, ref, lit) \
|
||||
_(FREF, R , ref, lit) \
|
||||
_(STRREF, N , ref, ref) \
|
||||
_(LREF, L , ___, ___) \
|
||||
\
|
||||
/* Loads and Stores. These must be in the same order. */ \
|
||||
_(ALOAD, L , ref, ___) \
|
||||
_(HLOAD, L , ref, ___) \
|
||||
_(ULOAD, L , ref, ___) \
|
||||
_(FLOAD, L , ref, lit) \
|
||||
_(XLOAD, L , ref, lit) \
|
||||
_(SLOAD, L , lit, lit) \
|
||||
_(VLOAD, L , ref, ___) \
|
||||
\
|
||||
_(ASTORE, S , ref, ref) \
|
||||
_(HSTORE, S , ref, ref) \
|
||||
_(USTORE, S , ref, ref) \
|
||||
_(FSTORE, S , ref, ref) \
|
||||
_(XSTORE, S , ref, ref) \
|
||||
\
|
||||
/* Allocations. */ \
|
||||
_(SNEW, N , ref, ref) /* CSE is ok, not marked as A. */ \
|
||||
_(XSNEW, A , ref, ref) \
|
||||
_(TNEW, AW, lit, lit) \
|
||||
_(TDUP, AW, ref, ___) \
|
||||
_(CNEW, AW, ref, ref) \
|
||||
_(CNEWI, NW, ref, ref) /* CSE is ok, not marked as A. */ \
|
||||
\
|
||||
/* Buffer operations. */ \
|
||||
_(BUFHDR, L , ref, lit) \
|
||||
_(BUFPUT, L , ref, ref) \
|
||||
_(BUFSTR, A , ref, ref) \
|
||||
\
|
||||
/* Barriers. */ \
|
||||
_(TBAR, S , ref, ___) \
|
||||
_(OBAR, S , ref, ref) \
|
||||
_(XBAR, S , ___, ___) \
|
||||
\
|
||||
/* Type conversions. */ \
|
||||
_(CONV, NW, ref, lit) \
|
||||
_(TOBIT, N , ref, ref) \
|
||||
_(TOSTR, N , ref, lit) \
|
||||
_(STRTO, N , ref, ___) \
|
||||
\
|
||||
/* Calls. */ \
|
||||
_(CALLN, N , ref, lit) \
|
||||
_(CALLA, A , ref, lit) \
|
||||
_(CALLL, L , ref, lit) \
|
||||
_(CALLS, S , ref, lit) \
|
||||
_(CALLXS, S , ref, ref) \
|
||||
_(CARG, N , ref, ref) \
|
||||
\
|
||||
/* End of list. */
|
||||
|
||||
/* IR opcodes (max. 256). */
|
||||
typedef enum {
|
||||
#define IRENUM(name, m, m1, m2) IR_##name,
|
||||
IRDEF(IRENUM)
|
||||
#undef IRENUM
|
||||
IR__MAX
|
||||
} IROp;
|
||||
|
||||
/* Stored opcode. */
|
||||
typedef uint8_t IROp1;
|
||||
|
||||
LJ_STATIC_ASSERT(((int)IR_EQ^1) == (int)IR_NE);
|
||||
LJ_STATIC_ASSERT(((int)IR_LT^1) == (int)IR_GE);
|
||||
LJ_STATIC_ASSERT(((int)IR_LE^1) == (int)IR_GT);
|
||||
LJ_STATIC_ASSERT(((int)IR_LT^3) == (int)IR_GT);
|
||||
LJ_STATIC_ASSERT(((int)IR_LT^4) == (int)IR_ULT);
|
||||
|
||||
/* Delta between xLOAD and xSTORE. */
|
||||
#define IRDELTA_L2S ((int)IR_ASTORE - (int)IR_ALOAD)
|
||||
|
||||
LJ_STATIC_ASSERT((int)IR_HLOAD + IRDELTA_L2S == (int)IR_HSTORE);
|
||||
LJ_STATIC_ASSERT((int)IR_ULOAD + IRDELTA_L2S == (int)IR_USTORE);
|
||||
LJ_STATIC_ASSERT((int)IR_FLOAD + IRDELTA_L2S == (int)IR_FSTORE);
|
||||
LJ_STATIC_ASSERT((int)IR_XLOAD + IRDELTA_L2S == (int)IR_XSTORE);
|
||||
|
||||
/* -- Named IR literals --------------------------------------------------- */
|
||||
|
||||
/* FPMATH sub-functions. ORDER FPM. */
|
||||
#define IRFPMDEF(_) \
|
||||
_(FLOOR) _(CEIL) _(TRUNC) /* Must be first and in this order. */ \
|
||||
_(SQRT) _(EXP) _(EXP2) _(LOG) _(LOG2) _(LOG10) \
|
||||
_(SIN) _(COS) _(TAN) \
|
||||
_(OTHER)
|
||||
|
||||
typedef enum {
|
||||
#define FPMENUM(name) IRFPM_##name,
|
||||
IRFPMDEF(FPMENUM)
|
||||
#undef FPMENUM
|
||||
IRFPM__MAX
|
||||
} IRFPMathOp;
|
||||
|
||||
/* FLOAD fields. */
|
||||
#define IRFLDEF(_) \
|
||||
_(STR_LEN, offsetof(GCstr, len)) \
|
||||
_(FUNC_ENV, offsetof(GCfunc, l.env)) \
|
||||
_(FUNC_PC, offsetof(GCfunc, l.pc)) \
|
||||
_(FUNC_FFID, offsetof(GCfunc, l.ffid)) \
|
||||
_(THREAD_ENV, offsetof(lua_State, env)) \
|
||||
_(TAB_META, offsetof(GCtab, metatable)) \
|
||||
_(TAB_ARRAY, offsetof(GCtab, array)) \
|
||||
_(TAB_NODE, offsetof(GCtab, node)) \
|
||||
_(TAB_ASIZE, offsetof(GCtab, asize)) \
|
||||
_(TAB_HMASK, offsetof(GCtab, hmask)) \
|
||||
_(TAB_NOMM, offsetof(GCtab, nomm)) \
|
||||
_(UDATA_META, offsetof(GCudata, metatable)) \
|
||||
_(UDATA_UDTYPE, offsetof(GCudata, udtype)) \
|
||||
_(UDATA_FILE, sizeof(GCudata)) \
|
||||
_(CDATA_CTYPEID, offsetof(GCcdata, ctypeid)) \
|
||||
_(CDATA_PTR, sizeof(GCcdata)) \
|
||||
_(CDATA_INT, sizeof(GCcdata)) \
|
||||
_(CDATA_INT64, sizeof(GCcdata)) \
|
||||
_(CDATA_INT64_4, sizeof(GCcdata) + 4)
|
||||
|
||||
typedef enum {
|
||||
#define FLENUM(name, ofs) IRFL_##name,
|
||||
IRFLDEF(FLENUM)
|
||||
#undef FLENUM
|
||||
IRFL__MAX
|
||||
} IRFieldID;
|
||||
|
||||
/* SLOAD mode bits, stored in op2. */
|
||||
#define IRSLOAD_PARENT 0x01 /* Coalesce with parent trace. */
|
||||
#define IRSLOAD_FRAME 0x02 /* Load 32 bits of ftsz. */
|
||||
#define IRSLOAD_TYPECHECK 0x04 /* Needs type check. */
|
||||
#define IRSLOAD_CONVERT 0x08 /* Number to integer conversion. */
|
||||
#define IRSLOAD_READONLY 0x10 /* Read-only, omit slot store. */
|
||||
#define IRSLOAD_INHERIT 0x20 /* Inherited by exits/side traces. */
|
||||
|
||||
/* XLOAD mode, stored in op2. */
|
||||
#define IRXLOAD_READONLY 1 /* Load from read-only data. */
|
||||
#define IRXLOAD_VOLATILE 2 /* Load from volatile data. */
|
||||
#define IRXLOAD_UNALIGNED 4 /* Unaligned load. */
|
||||
|
||||
/* BUFHDR mode, stored in op2. */
|
||||
#define IRBUFHDR_RESET 0 /* Reset buffer. */
|
||||
#define IRBUFHDR_APPEND 1 /* Append to buffer. */
|
||||
|
||||
/* CONV mode, stored in op2. */
|
||||
#define IRCONV_SRCMASK 0x001f /* Source IRType. */
|
||||
#define IRCONV_DSTMASK 0x03e0 /* Dest. IRType (also in ir->t). */
|
||||
#define IRCONV_DSH 5
|
||||
#define IRCONV_NUM_INT ((IRT_NUM<<IRCONV_DSH)|IRT_INT)
|
||||
#define IRCONV_INT_NUM ((IRT_INT<<IRCONV_DSH)|IRT_NUM)
|
||||
#define IRCONV_SEXT 0x0800 /* Sign-extend integer to integer. */
|
||||
#define IRCONV_MODEMASK 0x0fff
|
||||
#define IRCONV_CONVMASK 0xf000
|
||||
#define IRCONV_CSH 12
|
||||
/* Number to integer conversion mode. Ordered by strength of the checks. */
|
||||
#define IRCONV_TOBIT (0<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */
|
||||
#define IRCONV_ANY (1<<IRCONV_CSH) /* Any FP number is ok. */
|
||||
#define IRCONV_INDEX (2<<IRCONV_CSH) /* Check + special backprop rules. */
|
||||
#define IRCONV_CHECK (3<<IRCONV_CSH) /* Number checked for integerness. */
|
||||
|
||||
/* TOSTR mode, stored in op2. */
|
||||
#define IRTOSTR_INT 0 /* Convert integer to string. */
|
||||
#define IRTOSTR_NUM 1 /* Convert number to string. */
|
||||
#define IRTOSTR_CHAR 2 /* Convert char value to string. */
|
||||
|
||||
/* -- IR operands --------------------------------------------------------- */
|
||||
|
||||
/* IR operand mode (2 bit). */
|
||||
typedef enum {
|
||||
IRMref, /* IR reference. */
|
||||
IRMlit, /* 16 bit unsigned literal. */
|
||||
IRMcst, /* Constant literal: i, gcr or ptr. */
|
||||
IRMnone /* Unused operand. */
|
||||
} IRMode;
|
||||
#define IRM___ IRMnone
|
||||
|
||||
/* Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, Non-weak guard. */
|
||||
#define IRM_C 0x10
|
||||
|
||||
#define IRM_N 0x00
|
||||
#define IRM_R IRM_N
|
||||
#define IRM_A 0x20
|
||||
#define IRM_L 0x40
|
||||
#define IRM_S 0x60
|
||||
|
||||
#define IRM_W 0x80
|
||||
|
||||
#define IRM_NW (IRM_N|IRM_W)
|
||||
#define IRM_CW (IRM_C|IRM_W)
|
||||
#define IRM_AW (IRM_A|IRM_W)
|
||||
#define IRM_LW (IRM_L|IRM_W)
|
||||
|
||||
#define irm_op1(m) ((IRMode)((m)&3))
|
||||
#define irm_op2(m) ((IRMode)(((m)>>2)&3))
|
||||
#define irm_iscomm(m) ((m) & IRM_C)
|
||||
#define irm_kind(m) ((m) & IRM_S)
|
||||
|
||||
#define IRMODE(name, m, m1, m2) (((IRM##m1)|((IRM##m2)<<2)|(IRM_##m))^IRM_W),
|
||||
|
||||
LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1];
|
||||
|
||||
/* -- IR instruction types ------------------------------------------------ */
|
||||
|
||||
#define IRTSIZE_PGC (LJ_GC64 ? 8 : 4)
|
||||
|
||||
/* Map of itypes to non-negative numbers and their sizes. ORDER LJ_T.
|
||||
** LJ_TUPVAL/LJ_TTRACE never appear in a TValue. Use these itypes for
|
||||
** IRT_P32 and IRT_P64, which never escape the IR.
|
||||
** The various integers are only used in the IR and can only escape to
|
||||
** a TValue after implicit or explicit conversion. Their types must be
|
||||
** contiguous and next to IRT_NUM (see the typerange macros below).
|
||||
*/
|
||||
#define IRTDEF(_) \
|
||||
_(NIL, 4) _(FALSE, 4) _(TRUE, 4) _(LIGHTUD, LJ_64 ? 8 : 4) \
|
||||
_(STR, IRTSIZE_PGC) _(P32, 4) _(THREAD, IRTSIZE_PGC) _(PROTO, IRTSIZE_PGC) \
|
||||
_(FUNC, IRTSIZE_PGC) _(P64, 8) _(CDATA, IRTSIZE_PGC) _(TAB, IRTSIZE_PGC) \
|
||||
_(UDATA, IRTSIZE_PGC) \
|
||||
_(FLOAT, 4) _(NUM, 8) _(I8, 1) _(U8, 1) _(I16, 2) _(U16, 2) \
|
||||
_(INT, 4) _(U32, 4) _(I64, 8) _(U64, 8) \
|
||||
_(SOFTFP, 4) /* There is room for 8 more types. */
|
||||
|
||||
/* IR result type and flags (8 bit). */
|
||||
typedef enum {
|
||||
#define IRTENUM(name, size) IRT_##name,
|
||||
IRTDEF(IRTENUM)
|
||||
#undef IRTENUM
|
||||
IRT__MAX,
|
||||
|
||||
/* Native pointer type and the corresponding integer type. */
|
||||
IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32,
|
||||
IRT_PGC = LJ_GC64 ? IRT_P64 : IRT_P32,
|
||||
IRT_IGC = LJ_GC64 ? IRT_I64 : IRT_INT,
|
||||
IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT,
|
||||
IRT_UINTP = LJ_64 ? IRT_U64 : IRT_U32,
|
||||
|
||||
/* Additional flags. */
|
||||
IRT_MARK = 0x20, /* Marker for misc. purposes. */
|
||||
IRT_ISPHI = 0x40, /* Instruction is left or right PHI operand. */
|
||||
IRT_GUARD = 0x80, /* Instruction is a guard. */
|
||||
|
||||
/* Masks. */
|
||||
IRT_TYPE = 0x1f,
|
||||
IRT_T = 0xff
|
||||
} IRType;
|
||||
|
||||
#define irtype_ispri(irt) ((uint32_t)(irt) <= IRT_TRUE)
|
||||
|
||||
/* Stored IRType. */
|
||||
typedef struct IRType1 { uint8_t irt; } IRType1;
|
||||
|
||||
#define IRT(o, t) ((uint32_t)(((o)<<8) | (t)))
|
||||
#define IRTI(o) (IRT((o), IRT_INT))
|
||||
#define IRTN(o) (IRT((o), IRT_NUM))
|
||||
#define IRTG(o, t) (IRT((o), IRT_GUARD|(t)))
|
||||
#define IRTGI(o) (IRT((o), IRT_GUARD|IRT_INT))
|
||||
|
||||
#define irt_t(t) ((IRType)(t).irt)
|
||||
#define irt_type(t) ((IRType)((t).irt & IRT_TYPE))
|
||||
#define irt_sametype(t1, t2) ((((t1).irt ^ (t2).irt) & IRT_TYPE) == 0)
|
||||
#define irt_typerange(t, first, last) \
|
||||
((uint32_t)((t).irt & IRT_TYPE) - (uint32_t)(first) <= (uint32_t)(last-first))
|
||||
|
||||
#define irt_isnil(t) (irt_type(t) == IRT_NIL)
|
||||
#define irt_ispri(t) ((uint32_t)irt_type(t) <= IRT_TRUE)
|
||||
#define irt_islightud(t) (irt_type(t) == IRT_LIGHTUD)
|
||||
#define irt_isstr(t) (irt_type(t) == IRT_STR)
|
||||
#define irt_istab(t) (irt_type(t) == IRT_TAB)
|
||||
#define irt_iscdata(t) (irt_type(t) == IRT_CDATA)
|
||||
#define irt_isfloat(t) (irt_type(t) == IRT_FLOAT)
|
||||
#define irt_isnum(t) (irt_type(t) == IRT_NUM)
|
||||
#define irt_isint(t) (irt_type(t) == IRT_INT)
|
||||
#define irt_isi8(t) (irt_type(t) == IRT_I8)
|
||||
#define irt_isu8(t) (irt_type(t) == IRT_U8)
|
||||
#define irt_isi16(t) (irt_type(t) == IRT_I16)
|
||||
#define irt_isu16(t) (irt_type(t) == IRT_U16)
|
||||
#define irt_isu32(t) (irt_type(t) == IRT_U32)
|
||||
#define irt_isi64(t) (irt_type(t) == IRT_I64)
|
||||
#define irt_isu64(t) (irt_type(t) == IRT_U64)
|
||||
|
||||
#define irt_isfp(t) (irt_isnum(t) || irt_isfloat(t))
|
||||
#define irt_isinteger(t) (irt_typerange((t), IRT_I8, IRT_INT))
|
||||
#define irt_isgcv(t) (irt_typerange((t), IRT_STR, IRT_UDATA))
|
||||
#define irt_isaddr(t) (irt_typerange((t), IRT_LIGHTUD, IRT_UDATA))
|
||||
#define irt_isint64(t) (irt_typerange((t), IRT_I64, IRT_U64))
|
||||
|
||||
#if LJ_GC64
|
||||
#define IRT_IS64 \
|
||||
((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|\
|
||||
(1u<<IRT_LIGHTUD)|(1u<<IRT_STR)|(1u<<IRT_THREAD)|(1u<<IRT_PROTO)|\
|
||||
(1u<<IRT_FUNC)|(1u<<IRT_CDATA)|(1u<<IRT_TAB)|(1u<<IRT_UDATA))
|
||||
#elif LJ_64
|
||||
#define IRT_IS64 \
|
||||
((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|(1u<<IRT_LIGHTUD))
|
||||
#else
|
||||
#define IRT_IS64 \
|
||||
((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64))
|
||||
#endif
|
||||
|
||||
#define irt_is64(t) ((IRT_IS64 >> irt_type(t)) & 1)
|
||||
#define irt_is64orfp(t) (((IRT_IS64|(1u<<IRT_FLOAT))>>irt_type(t)) & 1)
|
||||
|
||||
#define irt_size(t) (lj_ir_type_size[irt_t((t))])
|
||||
|
||||
LJ_DATA const uint8_t lj_ir_type_size[];
|
||||
|
||||
static LJ_AINLINE IRType itype2irt(const TValue *tv)
|
||||
{
|
||||
if (tvisint(tv))
|
||||
return IRT_INT;
|
||||
else if (tvisnum(tv))
|
||||
return IRT_NUM;
|
||||
#if LJ_64 && !LJ_GC64
|
||||
else if (tvislightud(tv))
|
||||
return IRT_LIGHTUD;
|
||||
#endif
|
||||
else
|
||||
return (IRType)~itype(tv);
|
||||
}
|
||||
|
||||
static LJ_AINLINE uint32_t irt_toitype_(IRType t)
|
||||
{
|
||||
lua_assert(!LJ_64 || LJ_GC64 || t != IRT_LIGHTUD);
|
||||
if (LJ_DUALNUM && t > IRT_NUM) {
|
||||
return LJ_TISNUM;
|
||||
} else {
|
||||
lua_assert(t <= IRT_NUM);
|
||||
return ~(uint32_t)t;
|
||||
}
|
||||
}
|
||||
|
||||
#define irt_toitype(t) irt_toitype_(irt_type((t)))
|
||||
|
||||
#define irt_isguard(t) ((t).irt & IRT_GUARD)
|
||||
#define irt_ismarked(t) ((t).irt & IRT_MARK)
|
||||
#define irt_setmark(t) ((t).irt |= IRT_MARK)
|
||||
#define irt_clearmark(t) ((t).irt &= ~IRT_MARK)
|
||||
#define irt_isphi(t) ((t).irt & IRT_ISPHI)
|
||||
#define irt_setphi(t) ((t).irt |= IRT_ISPHI)
|
||||
#define irt_clearphi(t) ((t).irt &= ~IRT_ISPHI)
|
||||
|
||||
/* Stored combined IR opcode and type. */
|
||||
typedef uint16_t IROpT;
|
||||
|
||||
/* -- IR references ------------------------------------------------------- */
|
||||
|
||||
/* IR references. */
|
||||
typedef uint16_t IRRef1; /* One stored reference. */
|
||||
typedef uint32_t IRRef2; /* Two stored references. */
|
||||
typedef uint32_t IRRef; /* Used to pass around references. */
|
||||
|
||||
/* Fixed references. */
|
||||
enum {
|
||||
REF_BIAS = 0x8000,
|
||||
REF_TRUE = REF_BIAS-3,
|
||||
REF_FALSE = REF_BIAS-2,
|
||||
REF_NIL = REF_BIAS-1, /* \--- Constants grow downwards. */
|
||||
REF_BASE = REF_BIAS, /* /--- IR grows upwards. */
|
||||
REF_FIRST = REF_BIAS+1,
|
||||
REF_DROP = 0xffff
|
||||
};
|
||||
|
||||
/* Note: IRMlit operands must be < REF_BIAS, too!
|
||||
** This allows for fast and uniform manipulation of all operands
|
||||
** without looking up the operand mode in lj_ir_mode:
|
||||
** - CSE calculates the maximum reference of two operands.
|
||||
** This must work with mixed reference/literal operands, too.
|
||||
** - DCE marking only checks for operand >= REF_BIAS.
|
||||
** - LOOP needs to substitute reference operands.
|
||||
** Constant references and literals must not be modified.
|
||||
*/
|
||||
|
||||
#define IRREF2(lo, hi) ((IRRef2)(lo) | ((IRRef2)(hi) << 16))
|
||||
|
||||
#define irref_isk(ref) ((ref) < REF_BIAS)
|
||||
|
||||
/* Tagged IR references (32 bit).
|
||||
**
|
||||
** +-------+-------+---------------+
|
||||
** | irt | flags | ref |
|
||||
** +-------+-------+---------------+
|
||||
**
|
||||
** The tag holds a copy of the IRType and speeds up IR type checks.
|
||||
*/
|
||||
typedef uint32_t TRef;
|
||||
|
||||
#define TREF_REFMASK 0x0000ffff
|
||||
#define TREF_FRAME 0x00010000
|
||||
#define TREF_CONT 0x00020000
|
||||
|
||||
#define TREF(ref, t) ((TRef)((ref) + ((t)<<24)))
|
||||
|
||||
#define tref_ref(tr) ((IRRef1)(tr))
|
||||
#define tref_t(tr) ((IRType)((tr)>>24))
|
||||
#define tref_type(tr) ((IRType)(((tr)>>24) & IRT_TYPE))
|
||||
#define tref_typerange(tr, first, last) \
|
||||
((((tr)>>24) & IRT_TYPE) - (TRef)(first) <= (TRef)(last-first))
|
||||
|
||||
#define tref_istype(tr, t) (((tr) & (IRT_TYPE<<24)) == ((t)<<24))
|
||||
#define tref_isnil(tr) (tref_istype((tr), IRT_NIL))
|
||||
#define tref_isfalse(tr) (tref_istype((tr), IRT_FALSE))
|
||||
#define tref_istrue(tr) (tref_istype((tr), IRT_TRUE))
|
||||
#define tref_islightud(tr) (tref_istype((tr), IRT_LIGHTUD))
|
||||
#define tref_isstr(tr) (tref_istype((tr), IRT_STR))
|
||||
#define tref_isfunc(tr) (tref_istype((tr), IRT_FUNC))
|
||||
#define tref_iscdata(tr) (tref_istype((tr), IRT_CDATA))
|
||||
#define tref_istab(tr) (tref_istype((tr), IRT_TAB))
|
||||
#define tref_isudata(tr) (tref_istype((tr), IRT_UDATA))
|
||||
#define tref_isnum(tr) (tref_istype((tr), IRT_NUM))
|
||||
#define tref_isint(tr) (tref_istype((tr), IRT_INT))
|
||||
|
||||
#define tref_isbool(tr) (tref_typerange((tr), IRT_FALSE, IRT_TRUE))
|
||||
#define tref_ispri(tr) (tref_typerange((tr), IRT_NIL, IRT_TRUE))
|
||||
#define tref_istruecond(tr) (!tref_typerange((tr), IRT_NIL, IRT_FALSE))
|
||||
#define tref_isinteger(tr) (tref_typerange((tr), IRT_I8, IRT_INT))
|
||||
#define tref_isnumber(tr) (tref_typerange((tr), IRT_NUM, IRT_INT))
|
||||
#define tref_isnumber_str(tr) (tref_isnumber((tr)) || tref_isstr((tr)))
|
||||
#define tref_isgcv(tr) (tref_typerange((tr), IRT_STR, IRT_UDATA))
|
||||
|
||||
#define tref_isk(tr) (irref_isk(tref_ref((tr))))
|
||||
#define tref_isk2(tr1, tr2) (irref_isk(tref_ref((tr1) | (tr2))))
|
||||
|
||||
#define TREF_PRI(t) (TREF(REF_NIL-(t), (t)))
|
||||
#define TREF_NIL (TREF_PRI(IRT_NIL))
|
||||
#define TREF_FALSE (TREF_PRI(IRT_FALSE))
|
||||
#define TREF_TRUE (TREF_PRI(IRT_TRUE))
|
||||
|
||||
/* -- IR format ----------------------------------------------------------- */
|
||||
|
||||
/* IR instruction format (64 bit).
|
||||
**
|
||||
** 16 16 8 8 8 8
|
||||
** +-------+-------+---+---+---+---+
|
||||
** | op1 | op2 | t | o | r | s |
|
||||
** +-------+-------+---+---+---+---+
|
||||
** | op12/i/gco32 | ot | prev | (alternative fields in union)
|
||||
** +-------+-------+---+---+---+---+
|
||||
** | TValue/gco64 | (2nd IR slot for 64 bit constants)
|
||||
** +---------------+-------+-------+
|
||||
** 32 16 16
|
||||
**
|
||||
** prev is only valid prior to register allocation and then reused for r + s.
|
||||
*/
|
||||
|
||||
typedef union IRIns {
|
||||
struct {
|
||||
LJ_ENDIAN_LOHI(
|
||||
IRRef1 op1; /* IR operand 1. */
|
||||
, IRRef1 op2; /* IR operand 2. */
|
||||
)
|
||||
IROpT ot; /* IR opcode and type (overlaps t and o). */
|
||||
IRRef1 prev; /* Previous ins in same chain (overlaps r and s). */
|
||||
};
|
||||
struct {
|
||||
IRRef2 op12; /* IR operand 1 and 2 (overlaps op1 and op2). */
|
||||
LJ_ENDIAN_LOHI(
|
||||
IRType1 t; /* IR type. */
|
||||
, IROp1 o; /* IR opcode. */
|
||||
)
|
||||
LJ_ENDIAN_LOHI(
|
||||
uint8_t r; /* Register allocation (overlaps prev). */
|
||||
, uint8_t s; /* Spill slot allocation (overlaps prev). */
|
||||
)
|
||||
};
|
||||
int32_t i; /* 32 bit signed integer literal (overlaps op12). */
|
||||
GCRef gcr; /* GCobj constant (overlaps op12 or entire slot). */
|
||||
MRef ptr; /* Pointer constant (overlaps op12 or entire slot). */
|
||||
TValue tv; /* TValue constant (overlaps entire slot). */
|
||||
} IRIns;
|
||||
|
||||
#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)[LJ_GC64].gcr))
|
||||
#define ir_kstr(ir) (gco2str(ir_kgc((ir))))
|
||||
#define ir_ktab(ir) (gco2tab(ir_kgc((ir))))
|
||||
#define ir_kfunc(ir) (gco2func(ir_kgc((ir))))
|
||||
#define ir_kcdata(ir) (gco2cd(ir_kgc((ir))))
|
||||
#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, &(ir)[1].tv)
|
||||
#define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, &(ir)[1].tv)
|
||||
#define ir_k64(ir) \
|
||||
check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64 || \
|
||||
(LJ_GC64 && \
|
||||
((ir)->o == IR_KGC || \
|
||||
(ir)->o == IR_KPTR || (ir)->o == IR_KKPTR)), \
|
||||
&(ir)[1].tv)
|
||||
#define ir_kptr(ir) \
|
||||
check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, \
|
||||
mref((ir)[LJ_GC64].ptr, void))
|
||||
|
||||
/* A store or any other op with a non-weak guard has a side-effect. */
|
||||
static LJ_AINLINE int ir_sideeff(IRIns *ir)
|
||||
{
|
||||
return (((ir->t.irt | ~IRT_GUARD) & lj_ir_mode[ir->o]) >= IRM_S);
|
||||
}
|
||||
|
||||
LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W);
|
||||
|
||||
#endif
|
||||
@@ -1,343 +0,0 @@
|
||||
/*
|
||||
** IR CALL* instruction definitions.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_IRCALL_H
|
||||
#define _LJ_IRCALL_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_ir.h"
|
||||
#include "lj_jit.h"
|
||||
|
||||
/* C call info for CALL* instructions. */
|
||||
typedef struct CCallInfo {
|
||||
ASMFunction func; /* Function pointer. */
|
||||
uint32_t flags; /* Number of arguments and flags. */
|
||||
} CCallInfo;
|
||||
|
||||
#define CCI_NARGS(ci) ((ci)->flags & 0xff) /* # of args. */
|
||||
#define CCI_NARGS_MAX 32 /* Max. # of args. */
|
||||
|
||||
#define CCI_OTSHIFT 16
|
||||
#define CCI_OPTYPE(ci) ((ci)->flags >> CCI_OTSHIFT) /* Get op/type. */
|
||||
#define CCI_OPSHIFT 24
|
||||
#define CCI_OP(ci) ((ci)->flags >> CCI_OPSHIFT) /* Get op. */
|
||||
|
||||
#define CCI_CALL_N (IR_CALLN << CCI_OPSHIFT)
|
||||
#define CCI_CALL_A (IR_CALLA << CCI_OPSHIFT)
|
||||
#define CCI_CALL_L (IR_CALLL << CCI_OPSHIFT)
|
||||
#define CCI_CALL_S (IR_CALLS << CCI_OPSHIFT)
|
||||
#define CCI_CALL_FN (CCI_CALL_N|CCI_CC_FASTCALL)
|
||||
#define CCI_CALL_FL (CCI_CALL_L|CCI_CC_FASTCALL)
|
||||
#define CCI_CALL_FS (CCI_CALL_S|CCI_CC_FASTCALL)
|
||||
|
||||
/* C call info flags. */
|
||||
#define CCI_L 0x0100 /* Implicit L arg. */
|
||||
#define CCI_CASTU64 0x0200 /* Cast u64 result to number. */
|
||||
#define CCI_NOFPRCLOBBER 0x0400 /* Does not clobber any FPRs. */
|
||||
#define CCI_VARARG 0x0800 /* Vararg function. */
|
||||
|
||||
#define CCI_CC_MASK 0x3000 /* Calling convention mask. */
|
||||
#define CCI_CC_SHIFT 12
|
||||
/* ORDER CC */
|
||||
#define CCI_CC_CDECL 0x0000 /* Default cdecl calling convention. */
|
||||
#define CCI_CC_THISCALL 0x1000 /* Thiscall calling convention. */
|
||||
#define CCI_CC_FASTCALL 0x2000 /* Fastcall calling convention. */
|
||||
#define CCI_CC_STDCALL 0x3000 /* Stdcall calling convention. */
|
||||
|
||||
/* Extra args for SOFTFP, SPLIT 64 bit. */
|
||||
#define CCI_XARGS_SHIFT 14
|
||||
#define CCI_XARGS(ci) (((ci)->flags >> CCI_XARGS_SHIFT) & 3)
|
||||
#define CCI_XA (1u << CCI_XARGS_SHIFT)
|
||||
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
#define CCI_XNARGS(ci) (CCI_NARGS((ci)) + CCI_XARGS((ci)))
|
||||
#else
|
||||
#define CCI_XNARGS(ci) CCI_NARGS((ci))
|
||||
#endif
|
||||
|
||||
/* Helpers for conditional function definitions. */
|
||||
#define IRCALLCOND_ANY(x) x
|
||||
|
||||
#if LJ_TARGET_X86ORX64
|
||||
#define IRCALLCOND_FPMATH(x) NULL
|
||||
#else
|
||||
#define IRCALLCOND_FPMATH(x) x
|
||||
#endif
|
||||
|
||||
#if LJ_SOFTFP
|
||||
#define IRCALLCOND_SOFTFP(x) x
|
||||
#if LJ_HASFFI
|
||||
#define IRCALLCOND_SOFTFP_FFI(x) x
|
||||
#else
|
||||
#define IRCALLCOND_SOFTFP_FFI(x) NULL
|
||||
#endif
|
||||
#else
|
||||
#define IRCALLCOND_SOFTFP(x) NULL
|
||||
#define IRCALLCOND_SOFTFP_FFI(x) NULL
|
||||
#endif
|
||||
|
||||
#if LJ_SOFTFP && LJ_TARGET_MIPS32
|
||||
#define IRCALLCOND_SOFTFP_MIPS(x) x
|
||||
#else
|
||||
#define IRCALLCOND_SOFTFP_MIPS(x) NULL
|
||||
#endif
|
||||
|
||||
#define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS32)
|
||||
|
||||
#if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64)
|
||||
#define IRCALLCOND_FP64_FFI(x) x
|
||||
#else
|
||||
#define IRCALLCOND_FP64_FFI(x) NULL
|
||||
#endif
|
||||
|
||||
#if LJ_HASFFI
|
||||
#define IRCALLCOND_FFI(x) x
|
||||
#if LJ_32
|
||||
#define IRCALLCOND_FFI32(x) x
|
||||
#else
|
||||
#define IRCALLCOND_FFI32(x) NULL
|
||||
#endif
|
||||
#else
|
||||
#define IRCALLCOND_FFI(x) NULL
|
||||
#define IRCALLCOND_FFI32(x) NULL
|
||||
#endif
|
||||
|
||||
#if LJ_SOFTFP
|
||||
#define XA_FP CCI_XA
|
||||
#define XA2_FP (CCI_XA+CCI_XA)
|
||||
#else
|
||||
#define XA_FP 0
|
||||
#define XA2_FP 0
|
||||
#endif
|
||||
|
||||
#if LJ_32
|
||||
#define XA_64 CCI_XA
|
||||
#define XA2_64 (CCI_XA+CCI_XA)
|
||||
#else
|
||||
#define XA_64 0
|
||||
#define XA2_64 0
|
||||
#endif
|
||||
|
||||
/* Function definitions for CALL* instructions. */
|
||||
#define IRCALLDEF(_) \
|
||||
_(ANY, lj_str_cmp, 2, FN, INT, CCI_NOFPRCLOBBER) \
|
||||
_(ANY, lj_str_find, 4, N, PGC, 0) \
|
||||
_(ANY, lj_str_new, 3, S, STR, CCI_L) \
|
||||
_(ANY, lj_strscan_num, 2, FN, INT, 0) \
|
||||
_(ANY, lj_strfmt_int, 2, FN, STR, CCI_L) \
|
||||
_(ANY, lj_strfmt_num, 2, FN, STR, CCI_L) \
|
||||
_(ANY, lj_strfmt_char, 2, FN, STR, CCI_L) \
|
||||
_(ANY, lj_strfmt_putint, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_strfmt_putnum, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_strfmt_putquoted, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_strfmt_putfxint, 3, L, PGC, XA_64) \
|
||||
_(ANY, lj_strfmt_putfnum_int, 3, L, PGC, XA_FP) \
|
||||
_(ANY, lj_strfmt_putfnum_uint, 3, L, PGC, XA_FP) \
|
||||
_(ANY, lj_strfmt_putfnum, 3, L, PGC, XA_FP) \
|
||||
_(ANY, lj_strfmt_putfstr, 3, L, PGC, 0) \
|
||||
_(ANY, lj_strfmt_putfchar, 3, L, PGC, 0) \
|
||||
_(ANY, lj_buf_putmem, 3, S, PGC, 0) \
|
||||
_(ANY, lj_buf_putstr, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_buf_putchar, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_buf_putstr_reverse, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_buf_putstr_lower, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_buf_putstr_upper, 2, FL, PGC, 0) \
|
||||
_(ANY, lj_buf_putstr_rep, 3, L, PGC, 0) \
|
||||
_(ANY, lj_buf_puttab, 5, L, PGC, 0) \
|
||||
_(ANY, lj_buf_tostr, 1, FL, STR, 0) \
|
||||
_(ANY, lj_tab_new_ah, 3, A, TAB, CCI_L) \
|
||||
_(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \
|
||||
_(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \
|
||||
_(ANY, lj_tab_clear, 1, FS, NIL, 0) \
|
||||
_(ANY, lj_tab_newkey, 3, S, PGC, CCI_L) \
|
||||
_(ANY, lj_tab_len, 1, FL, INT, 0) \
|
||||
_(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
|
||||
_(ANY, lj_gc_barrieruv, 2, FS, NIL, 0) \
|
||||
_(ANY, lj_mem_newgco, 2, FS, PGC, CCI_L) \
|
||||
_(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64) \
|
||||
_(ANY, lj_vm_modi, 2, FN, INT, 0) \
|
||||
_(ANY, sinh, 1, N, NUM, XA_FP) \
|
||||
_(ANY, cosh, 1, N, NUM, XA_FP) \
|
||||
_(ANY, tanh, 1, N, NUM, XA_FP) \
|
||||
_(ANY, fputc, 2, S, INT, 0) \
|
||||
_(ANY, fwrite, 4, S, INT, 0) \
|
||||
_(ANY, fflush, 1, S, INT, 0) \
|
||||
/* ORDER FPM */ \
|
||||
_(FPMATH, lj_vm_floor, 1, N, NUM, XA_FP) \
|
||||
_(FPMATH, lj_vm_ceil, 1, N, NUM, XA_FP) \
|
||||
_(FPMATH, lj_vm_trunc, 1, N, NUM, XA_FP) \
|
||||
_(FPMATH, sqrt, 1, N, NUM, XA_FP) \
|
||||
_(ANY, exp, 1, N, NUM, XA_FP) \
|
||||
_(ANY, lj_vm_exp2, 1, N, NUM, XA_FP) \
|
||||
_(ANY, log, 1, N, NUM, XA_FP) \
|
||||
_(ANY, lj_vm_log2, 1, N, NUM, XA_FP) \
|
||||
_(ANY, log10, 1, N, NUM, XA_FP) \
|
||||
_(ANY, sin, 1, N, NUM, XA_FP) \
|
||||
_(ANY, cos, 1, N, NUM, XA_FP) \
|
||||
_(ANY, tan, 1, N, NUM, XA_FP) \
|
||||
_(ANY, lj_vm_powi, 2, N, NUM, XA_FP) \
|
||||
_(ANY, pow, 2, N, NUM, XA2_FP) \
|
||||
_(ANY, atan2, 2, N, NUM, XA2_FP) \
|
||||
_(ANY, ldexp, 2, N, NUM, XA_FP) \
|
||||
_(SOFTFP, lj_vm_tobit, 2, N, INT, 0) \
|
||||
_(SOFTFP, softfp_add, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_sub, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_mul, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_div, 4, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_cmp, 4, N, NIL, 0) \
|
||||
_(SOFTFP, softfp_i2d, 1, N, NUM, 0) \
|
||||
_(SOFTFP, softfp_d2i, 2, N, INT, 0) \
|
||||
_(SOFTFP_MIPS, lj_vm_sfmin, 4, N, NUM, 0) \
|
||||
_(SOFTFP_MIPS, lj_vm_sfmax, 4, N, NUM, 0) \
|
||||
_(SOFTFP_FFI, softfp_ui2d, 1, N, NUM, 0) \
|
||||
_(SOFTFP_FFI, softfp_f2d, 1, N, NUM, 0) \
|
||||
_(SOFTFP_FFI, softfp_d2ui, 2, N, INT, 0) \
|
||||
_(SOFTFP_FFI, softfp_d2f, 2, N, FLOAT, 0) \
|
||||
_(SOFTFP_FFI, softfp_i2f, 1, N, FLOAT, 0) \
|
||||
_(SOFTFP_FFI, softfp_ui2f, 1, N, FLOAT, 0) \
|
||||
_(SOFTFP_FFI, softfp_f2i, 1, N, INT, 0) \
|
||||
_(SOFTFP_FFI, softfp_f2ui, 1, N, INT, 0) \
|
||||
_(FP64_FFI, fp64_l2d, 1, N, NUM, XA_64) \
|
||||
_(FP64_FFI, fp64_ul2d, 1, N, NUM, XA_64) \
|
||||
_(FP64_FFI, fp64_l2f, 1, N, FLOAT, XA_64) \
|
||||
_(FP64_FFI, fp64_ul2f, 1, N, FLOAT, XA_64) \
|
||||
_(FP64_FFI, fp64_d2l, 1, N, I64, XA_FP) \
|
||||
_(FP64_FFI, fp64_d2ul, 1, N, U64, XA_FP) \
|
||||
_(FP64_FFI, fp64_f2l, 1, N, I64, 0) \
|
||||
_(FP64_FFI, fp64_f2ul, 1, N, U64, 0) \
|
||||
_(FFI, lj_carith_divi64, 2, N, I64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI, lj_carith_divu64, 2, N, U64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI, lj_carith_modi64, 2, N, I64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI, lj_carith_modu64, 2, N, U64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI, lj_carith_powi64, 2, N, I64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI, lj_carith_powu64, 2, N, U64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI, lj_cdata_newv, 4, S, CDATA, CCI_L) \
|
||||
_(FFI, lj_cdata_setfin, 4, S, NIL, CCI_L) \
|
||||
_(FFI, strlen, 1, L, INTP, 0) \
|
||||
_(FFI, memcpy, 3, S, PTR, 0) \
|
||||
_(FFI, memset, 3, S, PTR, 0) \
|
||||
_(FFI, lj_vm_errno, 0, S, INT, CCI_NOFPRCLOBBER) \
|
||||
_(FFI32, lj_carith_mul64, 2, N, I64, XA2_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI32, lj_carith_shl64, 2, N, U64, XA_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI32, lj_carith_shr64, 2, N, U64, XA_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI32, lj_carith_sar64, 2, N, U64, XA_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI32, lj_carith_rol64, 2, N, U64, XA_64|CCI_NOFPRCLOBBER) \
|
||||
_(FFI32, lj_carith_ror64, 2, N, U64, XA_64|CCI_NOFPRCLOBBER) \
|
||||
\
|
||||
/* End of list. */
|
||||
|
||||
typedef enum {
|
||||
#define IRCALLENUM(cond, name, nargs, kind, type, flags) IRCALL_##name,
|
||||
IRCALLDEF(IRCALLENUM)
|
||||
#undef IRCALLENUM
|
||||
IRCALL__MAX
|
||||
} IRCallID;
|
||||
|
||||
LJ_FUNC TRef lj_ir_call(jit_State *J, IRCallID id, ...);
|
||||
|
||||
LJ_DATA const CCallInfo lj_ir_callinfo[IRCALL__MAX+1];
|
||||
|
||||
/* Soft-float declarations. */
|
||||
#if LJ_SOFTFP
|
||||
#if LJ_TARGET_ARM
|
||||
#define softfp_add __aeabi_dadd
|
||||
#define softfp_sub __aeabi_dsub
|
||||
#define softfp_mul __aeabi_dmul
|
||||
#define softfp_div __aeabi_ddiv
|
||||
#define softfp_cmp __aeabi_cdcmple
|
||||
#define softfp_i2d __aeabi_i2d
|
||||
#define softfp_d2i __aeabi_d2iz
|
||||
#define softfp_ui2d __aeabi_ui2d
|
||||
#define softfp_f2d __aeabi_f2d
|
||||
#define softfp_d2ui __aeabi_d2uiz
|
||||
#define softfp_d2f __aeabi_d2f
|
||||
#define softfp_i2f __aeabi_i2f
|
||||
#define softfp_ui2f __aeabi_ui2f
|
||||
#define softfp_f2i __aeabi_f2iz
|
||||
#define softfp_f2ui __aeabi_f2uiz
|
||||
#define fp64_l2d __aeabi_l2d
|
||||
#define fp64_ul2d __aeabi_ul2d
|
||||
#define fp64_l2f __aeabi_l2f
|
||||
#define fp64_ul2f __aeabi_ul2f
|
||||
#if LJ_TARGET_IOS
|
||||
#define fp64_d2l __fixdfdi
|
||||
#define fp64_d2ul __fixunsdfdi
|
||||
#define fp64_f2l __fixsfdi
|
||||
#define fp64_f2ul __fixunssfdi
|
||||
#else
|
||||
#define fp64_d2l __aeabi_d2lz
|
||||
#define fp64_d2ul __aeabi_d2ulz
|
||||
#define fp64_f2l __aeabi_f2lz
|
||||
#define fp64_f2ul __aeabi_f2ulz
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS
|
||||
#define softfp_add __adddf3
|
||||
#define softfp_sub __subdf3
|
||||
#define softfp_mul __muldf3
|
||||
#define softfp_div __divdf3
|
||||
#define softfp_cmp __ledf2
|
||||
#define softfp_i2d __floatsidf
|
||||
#define softfp_d2i __fixdfsi
|
||||
#define softfp_ui2d __floatunsidf
|
||||
#define softfp_f2d __extendsfdf2
|
||||
#define softfp_d2ui __fixunsdfsi
|
||||
#define softfp_d2f __truncdfsf2
|
||||
#define softfp_i2f __floatsisf
|
||||
#define softfp_ui2f __floatunsisf
|
||||
#define softfp_f2i __fixsfsi
|
||||
#define softfp_f2ui __fixunssfsi
|
||||
#else
|
||||
#error "Missing soft-float definitions for target architecture"
|
||||
#endif
|
||||
extern double softfp_add(double a, double b);
|
||||
extern double softfp_sub(double a, double b);
|
||||
extern double softfp_mul(double a, double b);
|
||||
extern double softfp_div(double a, double b);
|
||||
extern void softfp_cmp(double a, double b);
|
||||
extern double softfp_i2d(int32_t a);
|
||||
extern int32_t softfp_d2i(double a);
|
||||
#if LJ_HASFFI
|
||||
extern double softfp_ui2d(uint32_t a);
|
||||
extern double softfp_f2d(float a);
|
||||
extern uint32_t softfp_d2ui(double a);
|
||||
extern float softfp_d2f(double a);
|
||||
extern float softfp_i2f(int32_t a);
|
||||
extern float softfp_ui2f(uint32_t a);
|
||||
extern int32_t softfp_f2i(float a);
|
||||
extern uint32_t softfp_f2ui(float a);
|
||||
#endif
|
||||
#if LJ_TARGET_MIPS
|
||||
extern double lj_vm_sfmin(double a, double b);
|
||||
extern double lj_vm_sfmax(double a, double b);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LJ_HASFFI && LJ_NEED_FP64 && !(LJ_TARGET_ARM && LJ_SOFTFP)
|
||||
#ifdef __GNUC__
|
||||
#define fp64_l2d __floatdidf
|
||||
#define fp64_ul2d __floatundidf
|
||||
#define fp64_l2f __floatdisf
|
||||
#define fp64_ul2f __floatundisf
|
||||
#define fp64_d2l __fixdfdi
|
||||
#define fp64_d2ul __fixunsdfdi
|
||||
#define fp64_f2l __fixsfdi
|
||||
#define fp64_f2ul __fixunssfdi
|
||||
#else
|
||||
#error "Missing fp64 helper definitions for this compiler"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64)
|
||||
extern double fp64_l2d(int64_t a);
|
||||
extern double fp64_ul2d(uint64_t a);
|
||||
extern float fp64_l2f(int64_t a);
|
||||
extern float fp64_ul2f(uint64_t a);
|
||||
extern int64_t fp64_d2l(double a);
|
||||
extern uint64_t fp64_d2ul(double a);
|
||||
extern int64_t fp64_f2l(float a);
|
||||
extern uint64_t fp64_f2ul(float a);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
** Common header for IR emitter and optimizations.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_IROPT_H
|
||||
#define _LJ_IROPT_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_jit.h"
|
||||
|
||||
#if LJ_HASJIT
|
||||
/* IR emitter. */
|
||||
LJ_FUNC void LJ_FASTCALL lj_ir_growtop(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_emit(jit_State *J);
|
||||
|
||||
/* Save current IR in J->fold.ins, but do not emit it (yet). */
|
||||
static LJ_AINLINE void lj_ir_set_(jit_State *J, uint16_t ot, IRRef1 a, IRRef1 b)
|
||||
{
|
||||
J->fold.ins.ot = ot; J->fold.ins.op1 = a; J->fold.ins.op2 = b;
|
||||
}
|
||||
|
||||
#define lj_ir_set(J, ot, a, b) \
|
||||
lj_ir_set_(J, (uint16_t)(ot), (IRRef1)(a), (IRRef1)(b))
|
||||
|
||||
/* Get ref of next IR instruction and optionally grow IR.
|
||||
** Note: this may invalidate all IRIns*!
|
||||
*/
|
||||
static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J)
|
||||
{
|
||||
IRRef ref = J->cur.nins;
|
||||
if (LJ_UNLIKELY(ref >= J->irtoplim)) lj_ir_growtop(J);
|
||||
J->cur.nins = ref + 1;
|
||||
return ref;
|
||||
}
|
||||
|
||||
LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs);
|
||||
|
||||
/* Interning of constants. */
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k);
|
||||
LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, uint64_t u64);
|
||||
LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64);
|
||||
LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n);
|
||||
LJ_FUNC TRef lj_ir_kint64(jit_State *J, uint64_t u64);
|
||||
LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t);
|
||||
LJ_FUNC TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr);
|
||||
LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t);
|
||||
LJ_FUNC TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot);
|
||||
LJ_FUNC TRef lj_ir_ktrace(jit_State *J);
|
||||
|
||||
#if LJ_64
|
||||
#define lj_ir_kintp(J, k) lj_ir_kint64(J, (uint64_t)(k))
|
||||
#else
|
||||
#define lj_ir_kintp(J, k) lj_ir_kint(J, (int32_t)(k))
|
||||
#endif
|
||||
|
||||
static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n)
|
||||
{
|
||||
TValue tv;
|
||||
tv.n = n;
|
||||
return lj_ir_knum_u64(J, tv.u64);
|
||||
}
|
||||
|
||||
#define lj_ir_kstr(J, str) lj_ir_kgc(J, obj2gco((str)), IRT_STR)
|
||||
#define lj_ir_ktab(J, tab) lj_ir_kgc(J, obj2gco((tab)), IRT_TAB)
|
||||
#define lj_ir_kfunc(J, func) lj_ir_kgc(J, obj2gco((func)), IRT_FUNC)
|
||||
#define lj_ir_kptr(J, ptr) lj_ir_kptr_(J, IR_KPTR, (ptr))
|
||||
#define lj_ir_kkptr(J, ptr) lj_ir_kptr_(J, IR_KKPTR, (ptr))
|
||||
|
||||
/* Special FP constants. */
|
||||
#define lj_ir_knum_zero(J) lj_ir_knum_u64(J, U64x(00000000,00000000))
|
||||
#define lj_ir_knum_one(J) lj_ir_knum_u64(J, U64x(3ff00000,00000000))
|
||||
#define lj_ir_knum_tobit(J) lj_ir_knum_u64(J, U64x(43380000,00000000))
|
||||
|
||||
/* Special 128 bit SIMD constants. */
|
||||
#define lj_ir_ksimd(J, idx) \
|
||||
lj_ir_ggfload(J, IRT_NUM, (uintptr_t)LJ_KSIMD(J, idx) - (uintptr_t)J2GG(J))
|
||||
|
||||
/* Access to constants. */
|
||||
LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir);
|
||||
|
||||
/* Convert IR operand types. */
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr);
|
||||
|
||||
/* Miscellaneous IR ops. */
|
||||
LJ_FUNC int lj_ir_numcmp(lua_Number a, lua_Number b, IROp op);
|
||||
LJ_FUNC int lj_ir_strcmp(GCstr *a, GCstr *b, IROp op);
|
||||
LJ_FUNC void lj_ir_rollback(jit_State *J, IRRef ref);
|
||||
|
||||
/* Emit IR instructions with on-the-fly optimizations. */
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fold(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_cse(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_cselim(jit_State *J, IRRef lim);
|
||||
|
||||
/* Special return values for the fold functions. */
|
||||
enum {
|
||||
NEXTFOLD, /* Couldn't fold, pass on. */
|
||||
RETRYFOLD, /* Retry fold with modified fins. */
|
||||
KINTFOLD, /* Return ref for int constant in fins->i. */
|
||||
FAILFOLD, /* Guard would always fail. */
|
||||
DROPFOLD, /* Guard eliminated. */
|
||||
MAX_FOLD
|
||||
};
|
||||
|
||||
#define INTFOLD(k) ((J->fold.ins.i = (k)), (TRef)KINTFOLD)
|
||||
#define INT64FOLD(k) (lj_ir_kint64(J, (k)))
|
||||
#define CONDFOLD(cond) ((TRef)FAILFOLD + (TRef)(cond))
|
||||
#define LEFTFOLD (J->fold.ins.op1)
|
||||
#define RIGHTFOLD (J->fold.ins.op2)
|
||||
#define CSEFOLD (lj_opt_cse(J))
|
||||
#define EMITFOLD (lj_ir_emit(J))
|
||||
|
||||
/* Load/store forwarding. */
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_aload(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hrefk(jit_State *J);
|
||||
LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J);
|
||||
LJ_FUNC int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim);
|
||||
LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref);
|
||||
|
||||
/* Dead-store elimination. */
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_ustore(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_fstore(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J);
|
||||
|
||||
/* Narrowing. */
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_convert(jit_State *J);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_index(jit_State *J, TRef key);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_toint(jit_State *J, TRef tr);
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_tobit(jit_State *J, TRef tr);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key);
|
||||
#endif
|
||||
LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
|
||||
TValue *vb, TValue *vc, IROp op);
|
||||
LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc);
|
||||
LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc);
|
||||
LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc);
|
||||
LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);
|
||||
|
||||
/* Optimization passes. */
|
||||
LJ_FUNC void lj_opt_dce(jit_State *J);
|
||||
LJ_FUNC int lj_opt_loop(jit_State *J);
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
LJ_FUNC void lj_opt_split(jit_State *J);
|
||||
#else
|
||||
#define lj_opt_split(J) UNUSED(J)
|
||||
#endif
|
||||
LJ_FUNC void lj_opt_sink(jit_State *J);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
** Common definitions for the JIT compiler.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_JIT_H
|
||||
#define _LJ_JIT_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_ir.h"
|
||||
|
||||
/* JIT engine flags. */
|
||||
#define JIT_F_ON 0x00000001
|
||||
|
||||
/* CPU-specific JIT engine flags. */
|
||||
#if LJ_TARGET_X86ORX64
|
||||
#define JIT_F_SSE2 0x00000010
|
||||
#define JIT_F_SSE3 0x00000020
|
||||
#define JIT_F_SSE4_1 0x00000040
|
||||
#define JIT_F_PREFER_IMUL 0x00000080
|
||||
#define JIT_F_LEA_AGU 0x00000100
|
||||
#define JIT_F_BMI2 0x00000200
|
||||
|
||||
/* Names for the CPU-specific flags. Must match the order above. */
|
||||
#define JIT_F_CPU_FIRST JIT_F_SSE2
|
||||
#define JIT_F_CPUSTRING "\4SSE2\4SSE3\6SSE4.1\3AMD\4ATOM\4BMI2"
|
||||
#elif LJ_TARGET_ARM
|
||||
#define JIT_F_ARMV6_ 0x00000010
|
||||
#define JIT_F_ARMV6T2_ 0x00000020
|
||||
#define JIT_F_ARMV7 0x00000040
|
||||
#define JIT_F_VFPV2 0x00000080
|
||||
#define JIT_F_VFPV3 0x00000100
|
||||
|
||||
#define JIT_F_ARMV6 (JIT_F_ARMV6_|JIT_F_ARMV6T2_|JIT_F_ARMV7)
|
||||
#define JIT_F_ARMV6T2 (JIT_F_ARMV6T2_|JIT_F_ARMV7)
|
||||
#define JIT_F_VFP (JIT_F_VFPV2|JIT_F_VFPV3)
|
||||
|
||||
/* Names for the CPU-specific flags. Must match the order above. */
|
||||
#define JIT_F_CPU_FIRST JIT_F_ARMV6_
|
||||
#define JIT_F_CPUSTRING "\5ARMv6\7ARMv6T2\5ARMv7\5VFPv2\5VFPv3"
|
||||
#elif LJ_TARGET_PPC
|
||||
#define JIT_F_SQRT 0x00000010
|
||||
#define JIT_F_ROUND 0x00000020
|
||||
|
||||
/* Names for the CPU-specific flags. Must match the order above. */
|
||||
#define JIT_F_CPU_FIRST JIT_F_SQRT
|
||||
#define JIT_F_CPUSTRING "\4SQRT\5ROUND"
|
||||
#elif LJ_TARGET_MIPS
|
||||
#define JIT_F_MIPSXXR2 0x00000010
|
||||
|
||||
/* Names for the CPU-specific flags. Must match the order above. */
|
||||
#define JIT_F_CPU_FIRST JIT_F_MIPSXXR2
|
||||
#if LJ_TARGET_MIPS32
|
||||
#define JIT_F_CPUSTRING "\010MIPS32R2"
|
||||
#else
|
||||
#define JIT_F_CPUSTRING "\010MIPS64R2"
|
||||
#endif
|
||||
#else
|
||||
#define JIT_F_CPU_FIRST 0
|
||||
#define JIT_F_CPUSTRING ""
|
||||
#endif
|
||||
|
||||
/* Optimization flags. */
|
||||
#define JIT_F_OPT_MASK 0x0fff0000
|
||||
|
||||
#define JIT_F_OPT_FOLD 0x00010000
|
||||
#define JIT_F_OPT_CSE 0x00020000
|
||||
#define JIT_F_OPT_DCE 0x00040000
|
||||
#define JIT_F_OPT_FWD 0x00080000
|
||||
#define JIT_F_OPT_DSE 0x00100000
|
||||
#define JIT_F_OPT_NARROW 0x00200000
|
||||
#define JIT_F_OPT_LOOP 0x00400000
|
||||
#define JIT_F_OPT_ABC 0x00800000
|
||||
#define JIT_F_OPT_SINK 0x01000000
|
||||
#define JIT_F_OPT_FUSE 0x02000000
|
||||
|
||||
/* Optimizations names for -O. Must match the order above. */
|
||||
#define JIT_F_OPT_FIRST JIT_F_OPT_FOLD
|
||||
#define JIT_F_OPTSTRING \
|
||||
"\4fold\3cse\3dce\3fwd\3dse\6narrow\4loop\3abc\4sink\4fuse"
|
||||
|
||||
/* Optimization levels set a fixed combination of flags. */
|
||||
#define JIT_F_OPT_0 0
|
||||
#define JIT_F_OPT_1 (JIT_F_OPT_FOLD|JIT_F_OPT_CSE|JIT_F_OPT_DCE)
|
||||
#define JIT_F_OPT_2 (JIT_F_OPT_1|JIT_F_OPT_NARROW|JIT_F_OPT_LOOP)
|
||||
#define JIT_F_OPT_3 (JIT_F_OPT_2|\
|
||||
JIT_F_OPT_FWD|JIT_F_OPT_DSE|JIT_F_OPT_ABC|JIT_F_OPT_SINK|JIT_F_OPT_FUSE)
|
||||
#define JIT_F_OPT_DEFAULT JIT_F_OPT_3
|
||||
|
||||
#if LJ_TARGET_WINDOWS || LJ_64
|
||||
/* See: http://blogs.msdn.com/oldnewthing/archive/2003/10/08/55239.aspx */
|
||||
#define JIT_P_sizemcode_DEFAULT 64
|
||||
#else
|
||||
/* Could go as low as 4K, but the mmap() overhead would be rather high. */
|
||||
#define JIT_P_sizemcode_DEFAULT 32
|
||||
#endif
|
||||
|
||||
/* Optimization parameters and their defaults. Length is a char in octal! */
|
||||
#define JIT_PARAMDEF(_) \
|
||||
_(\010, maxtrace, 1000) /* Max. # of traces in cache. */ \
|
||||
_(\011, maxrecord, 4000) /* Max. # of recorded IR instructions. */ \
|
||||
_(\012, maxirconst, 500) /* Max. # of IR constants of a trace. */ \
|
||||
_(\007, maxside, 100) /* Max. # of side traces of a root trace. */ \
|
||||
_(\007, maxsnap, 500) /* Max. # of snapshots for a trace. */ \
|
||||
_(\011, minstitch, 0) /* Min. # of IR ins for a stitched trace. */ \
|
||||
\
|
||||
_(\007, hotloop, 56) /* # of iter. to detect a hot loop/call. */ \
|
||||
_(\007, hotexit, 10) /* # of taken exits to start a side trace. */ \
|
||||
_(\007, tryside, 4) /* # of attempts to compile a side trace. */ \
|
||||
\
|
||||
_(\012, instunroll, 4) /* Max. unroll for instable loops. */ \
|
||||
_(\012, loopunroll, 15) /* Max. unroll for loop ops in side traces. */ \
|
||||
_(\012, callunroll, 3) /* Max. unroll for recursive calls. */ \
|
||||
_(\011, recunroll, 2) /* Min. unroll for true recursion. */ \
|
||||
\
|
||||
/* Size of each machine code area (in KBytes). */ \
|
||||
_(\011, sizemcode, JIT_P_sizemcode_DEFAULT) \
|
||||
/* Max. total size of all machine code areas (in KBytes). */ \
|
||||
_(\010, maxmcode, 512) \
|
||||
/* End of list. */
|
||||
|
||||
enum {
|
||||
#define JIT_PARAMENUM(len, name, value) JIT_P_##name,
|
||||
JIT_PARAMDEF(JIT_PARAMENUM)
|
||||
#undef JIT_PARAMENUM
|
||||
JIT_P__MAX
|
||||
};
|
||||
|
||||
#define JIT_PARAMSTR(len, name, value) #len #name
|
||||
#define JIT_P_STRING JIT_PARAMDEF(JIT_PARAMSTR)
|
||||
|
||||
/* Trace compiler state. */
|
||||
typedef enum {
|
||||
LJ_TRACE_IDLE, /* Trace compiler idle. */
|
||||
LJ_TRACE_ACTIVE = 0x10,
|
||||
LJ_TRACE_RECORD, /* Bytecode recording active. */
|
||||
LJ_TRACE_START, /* New trace started. */
|
||||
LJ_TRACE_END, /* End of trace. */
|
||||
LJ_TRACE_ASM, /* Assemble trace. */
|
||||
LJ_TRACE_ERR /* Trace aborted with error. */
|
||||
} TraceState;
|
||||
|
||||
/* Post-processing action. */
|
||||
typedef enum {
|
||||
LJ_POST_NONE, /* No action. */
|
||||
LJ_POST_FIXCOMP, /* Fixup comparison and emit pending guard. */
|
||||
LJ_POST_FIXGUARD, /* Fixup and emit pending guard. */
|
||||
LJ_POST_FIXGUARDSNAP, /* Fixup and emit pending guard and snapshot. */
|
||||
LJ_POST_FIXBOOL, /* Fixup boolean result. */
|
||||
LJ_POST_FIXCONST, /* Fixup constant results. */
|
||||
LJ_POST_FFRETRY /* Suppress recording of retried fast functions. */
|
||||
} PostProc;
|
||||
|
||||
/* Machine code type. */
|
||||
#if LJ_TARGET_X86ORX64
|
||||
typedef uint8_t MCode;
|
||||
#else
|
||||
typedef uint32_t MCode;
|
||||
#endif
|
||||
|
||||
/* Stack snapshot header. */
|
||||
typedef struct SnapShot {
|
||||
uint16_t mapofs; /* Offset into snapshot map. */
|
||||
IRRef1 ref; /* First IR ref for this snapshot. */
|
||||
uint8_t nslots; /* Number of valid slots. */
|
||||
uint8_t topslot; /* Maximum frame extent. */
|
||||
uint8_t nent; /* Number of compressed entries. */
|
||||
uint8_t count; /* Count of taken exits for this snapshot. */
|
||||
} SnapShot;
|
||||
|
||||
#define SNAPCOUNT_DONE 255 /* Already compiled and linked a side trace. */
|
||||
|
||||
/* Compressed snapshot entry. */
|
||||
typedef uint32_t SnapEntry;
|
||||
|
||||
#define SNAP_FRAME 0x010000 /* Frame slot. */
|
||||
#define SNAP_CONT 0x020000 /* Continuation slot. */
|
||||
#define SNAP_NORESTORE 0x040000 /* No need to restore slot. */
|
||||
#define SNAP_SOFTFPNUM 0x080000 /* Soft-float number. */
|
||||
LJ_STATIC_ASSERT(SNAP_FRAME == TREF_FRAME);
|
||||
LJ_STATIC_ASSERT(SNAP_CONT == TREF_CONT);
|
||||
|
||||
#define SNAP(slot, flags, ref) (((SnapEntry)(slot) << 24) + (flags) + (ref))
|
||||
#define SNAP_TR(slot, tr) \
|
||||
(((SnapEntry)(slot) << 24) + ((tr) & (TREF_CONT|TREF_FRAME|TREF_REFMASK)))
|
||||
#if !LJ_FR2
|
||||
#define SNAP_MKPC(pc) ((SnapEntry)u32ptr(pc))
|
||||
#endif
|
||||
#define SNAP_MKFTSZ(ftsz) ((SnapEntry)(ftsz))
|
||||
#define snap_ref(sn) ((sn) & 0xffff)
|
||||
#define snap_slot(sn) ((BCReg)((sn) >> 24))
|
||||
#define snap_isframe(sn) ((sn) & SNAP_FRAME)
|
||||
#define snap_setref(sn, ref) (((sn) & (0xffff0000&~SNAP_NORESTORE)) | (ref))
|
||||
|
||||
static LJ_AINLINE const BCIns *snap_pc(SnapEntry *sn)
|
||||
{
|
||||
#if LJ_FR2
|
||||
uint64_t pcbase;
|
||||
memcpy(&pcbase, sn, sizeof(uint64_t));
|
||||
return (const BCIns *)(pcbase >> 8);
|
||||
#else
|
||||
return (const BCIns *)(uintptr_t)*sn;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Snapshot and exit numbers. */
|
||||
typedef uint32_t SnapNo;
|
||||
typedef uint32_t ExitNo;
|
||||
|
||||
/* Trace number. */
|
||||
typedef uint32_t TraceNo; /* Used to pass around trace numbers. */
|
||||
typedef uint16_t TraceNo1; /* Stored trace number. */
|
||||
|
||||
/* Type of link. ORDER LJ_TRLINK */
|
||||
typedef enum {
|
||||
LJ_TRLINK_NONE, /* Incomplete trace. No link, yet. */
|
||||
LJ_TRLINK_ROOT, /* Link to other root trace. */
|
||||
LJ_TRLINK_LOOP, /* Loop to same trace. */
|
||||
LJ_TRLINK_TAILREC, /* Tail-recursion. */
|
||||
LJ_TRLINK_UPREC, /* Up-recursion. */
|
||||
LJ_TRLINK_DOWNREC, /* Down-recursion. */
|
||||
LJ_TRLINK_INTERP, /* Fallback to interpreter. */
|
||||
LJ_TRLINK_RETURN, /* Return to interpreter. */
|
||||
LJ_TRLINK_STITCH /* Trace stitching. */
|
||||
} TraceLink;
|
||||
|
||||
/* Trace object. */
|
||||
typedef struct GCtrace {
|
||||
GCHeader;
|
||||
uint8_t topslot; /* Top stack slot already checked to be allocated. */
|
||||
uint8_t linktype; /* Type of link. */
|
||||
IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */
|
||||
#if LJ_GC64
|
||||
uint32_t unused_gc64;
|
||||
#endif
|
||||
GCRef gclist;
|
||||
IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */
|
||||
IRRef nk; /* Lowest IR constant. Biased with REF_BIAS. */
|
||||
uint16_t nsnap; /* Number of snapshots. */
|
||||
uint16_t nsnapmap; /* Number of snapshot map elements. */
|
||||
SnapShot *snap; /* Snapshot array. */
|
||||
SnapEntry *snapmap; /* Snapshot map. */
|
||||
GCRef startpt; /* Starting prototype. */
|
||||
MRef startpc; /* Bytecode PC of starting instruction. */
|
||||
BCIns startins; /* Original bytecode of starting instruction. */
|
||||
MSize szmcode; /* Size of machine code. */
|
||||
MCode *mcode; /* Start of machine code. */
|
||||
MSize mcloop; /* Offset of loop start in machine code. */
|
||||
uint16_t nchild; /* Number of child traces (root trace only). */
|
||||
uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */
|
||||
TraceNo1 traceno; /* Trace number. */
|
||||
TraceNo1 link; /* Linked trace (or self for loops). */
|
||||
TraceNo1 root; /* Root trace of side trace (or 0 for root traces). */
|
||||
TraceNo1 nextroot; /* Next root trace for same prototype. */
|
||||
TraceNo1 nextside; /* Next side trace of same root trace. */
|
||||
uint8_t sinktags; /* Trace has SINK tags. */
|
||||
uint8_t unused1;
|
||||
#ifdef LUAJIT_USE_GDBJIT
|
||||
void *gdbjit_entry; /* GDB JIT entry. */
|
||||
#endif
|
||||
} GCtrace;
|
||||
|
||||
#define gco2trace(o) check_exp((o)->gch.gct == ~LJ_TTRACE, (GCtrace *)(o))
|
||||
#define traceref(J, n) \
|
||||
check_exp((n)>0 && (MSize)(n)<J->sizetrace, (GCtrace *)gcref(J->trace[(n)]))
|
||||
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCtrace, gclist));
|
||||
|
||||
static LJ_AINLINE MSize snap_nextofs(GCtrace *T, SnapShot *snap)
|
||||
{
|
||||
if (snap+1 == &T->snap[T->nsnap])
|
||||
return T->nsnapmap;
|
||||
else
|
||||
return (snap+1)->mapofs;
|
||||
}
|
||||
|
||||
/* Round-robin penalty cache for bytecodes leading to aborted traces. */
|
||||
typedef struct HotPenalty {
|
||||
MRef pc; /* Starting bytecode PC. */
|
||||
uint16_t val; /* Penalty value, i.e. hotcount start. */
|
||||
uint16_t reason; /* Abort reason (really TraceErr). */
|
||||
} HotPenalty;
|
||||
|
||||
#define PENALTY_SLOTS 64 /* Penalty cache slot. Must be a power of 2. */
|
||||
#define PENALTY_MIN (36*2) /* Minimum penalty value. */
|
||||
#define PENALTY_MAX 60000 /* Maximum penalty value. */
|
||||
#define PENALTY_RNDBITS 4 /* # of random bits to add to penalty value. */
|
||||
|
||||
/* Round-robin backpropagation cache for narrowing conversions. */
|
||||
typedef struct BPropEntry {
|
||||
IRRef1 key; /* Key: original reference. */
|
||||
IRRef1 val; /* Value: reference after conversion. */
|
||||
IRRef mode; /* Mode for this entry (currently IRCONV_*). */
|
||||
} BPropEntry;
|
||||
|
||||
/* Number of slots for the backpropagation cache. Must be a power of 2. */
|
||||
#define BPROP_SLOTS 16
|
||||
|
||||
/* Scalar evolution analysis cache. */
|
||||
typedef struct ScEvEntry {
|
||||
MRef pc; /* Bytecode PC of FORI. */
|
||||
IRRef1 idx; /* Index reference. */
|
||||
IRRef1 start; /* Constant start reference. */
|
||||
IRRef1 stop; /* Constant stop reference. */
|
||||
IRRef1 step; /* Constant step reference. */
|
||||
IRType1 t; /* Scalar type. */
|
||||
uint8_t dir; /* Direction. 1: +, 0: -. */
|
||||
} ScEvEntry;
|
||||
|
||||
/* Reverse bytecode map (IRRef -> PC). Only for selected instructions. */
|
||||
typedef struct RBCHashEntry {
|
||||
MRef pc; /* Bytecode PC. */
|
||||
GCRef pt; /* Prototype. */
|
||||
IRRef ref; /* IR reference. */
|
||||
} RBCHashEntry;
|
||||
|
||||
/* Number of slots in the reverse bytecode hash table. Must be a power of 2. */
|
||||
#define RBCHASH_SLOTS 8
|
||||
|
||||
/* 128 bit SIMD constants. */
|
||||
enum {
|
||||
LJ_KSIMD_ABS,
|
||||
LJ_KSIMD_NEG,
|
||||
LJ_KSIMD__MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
#if LJ_TARGET_X86ORX64
|
||||
LJ_K64_TOBIT, /* 2^52 + 2^51 */
|
||||
LJ_K64_2P64, /* 2^64 */
|
||||
LJ_K64_M2P64, /* -2^64 */
|
||||
#if LJ_32
|
||||
LJ_K64_M2P64_31, /* -2^64 or -2^31 */
|
||||
#else
|
||||
LJ_K64_M2P64_31 = LJ_K64_M2P64,
|
||||
#endif
|
||||
#endif
|
||||
#if LJ_TARGET_MIPS
|
||||
LJ_K64_2P31, /* 2^31 */
|
||||
#if LJ_64
|
||||
LJ_K64_2P63, /* 2^63 */
|
||||
LJ_K64_M2P64, /* -2^64 */
|
||||
#endif
|
||||
#endif
|
||||
LJ_K64__MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
#if LJ_TARGET_X86ORX64
|
||||
LJ_K32_M2P64_31, /* -2^64 or -2^31 */
|
||||
#endif
|
||||
#if LJ_TARGET_PPC
|
||||
LJ_K32_2P52_2P31, /* 2^52 + 2^31 */
|
||||
LJ_K32_2P52, /* 2^52 */
|
||||
#endif
|
||||
#if LJ_TARGET_PPC || LJ_TARGET_MIPS
|
||||
LJ_K32_2P31, /* 2^31 */
|
||||
#endif
|
||||
#if LJ_TARGET_MIPS64
|
||||
LJ_K32_2P63, /* 2^63 */
|
||||
LJ_K32_M2P64, /* -2^64 */
|
||||
#endif
|
||||
LJ_K32__MAX
|
||||
};
|
||||
|
||||
/* Get 16 byte aligned pointer to SIMD constant. */
|
||||
#define LJ_KSIMD(J, n) \
|
||||
((TValue *)(((intptr_t)&J->ksimd[2*(n)] + 15) & ~(intptr_t)15))
|
||||
|
||||
/* Set/reset flag to activate the SPLIT pass for the current trace. */
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
#define lj_needsplit(J) (J->needsplit = 1)
|
||||
#define lj_resetsplit(J) (J->needsplit = 0)
|
||||
#else
|
||||
#define lj_needsplit(J) UNUSED(J)
|
||||
#define lj_resetsplit(J) UNUSED(J)
|
||||
#endif
|
||||
|
||||
/* Fold state is used to fold instructions on-the-fly. */
|
||||
typedef struct FoldState {
|
||||
IRIns ins; /* Currently emitted instruction. */
|
||||
IRIns left[2]; /* Instruction referenced by left operand. */
|
||||
IRIns right[2]; /* Instruction referenced by right operand. */
|
||||
} FoldState;
|
||||
|
||||
/* JIT compiler state. */
|
||||
typedef struct jit_State {
|
||||
GCtrace cur; /* Current trace. */
|
||||
GCtrace *curfinal; /* Final address of current trace (set during asm). */
|
||||
|
||||
lua_State *L; /* Current Lua state. */
|
||||
const BCIns *pc; /* Current PC. */
|
||||
GCfunc *fn; /* Current function. */
|
||||
GCproto *pt; /* Current prototype. */
|
||||
TRef *base; /* Current frame base, points into J->slots. */
|
||||
|
||||
uint32_t flags; /* JIT engine flags. */
|
||||
BCReg maxslot; /* Relative to baseslot. */
|
||||
BCReg baseslot; /* Current frame base, offset into J->slots. */
|
||||
|
||||
uint8_t mergesnap; /* Allowed to merge with next snapshot. */
|
||||
uint8_t needsnap; /* Need snapshot before recording next bytecode. */
|
||||
IRType1 guardemit; /* Accumulated IRT_GUARD for emitted instructions. */
|
||||
uint8_t bcskip; /* Number of bytecode instructions to skip. */
|
||||
|
||||
FoldState fold; /* Fold state. */
|
||||
|
||||
const BCIns *bc_min; /* Start of allowed bytecode range for root trace. */
|
||||
MSize bc_extent; /* Extent of the range. */
|
||||
|
||||
TraceState state; /* Trace compiler state. */
|
||||
|
||||
int32_t instunroll; /* Unroll counter for instable loops. */
|
||||
int32_t loopunroll; /* Unroll counter for loop ops in side traces. */
|
||||
int32_t tailcalled; /* Number of successive tailcalls. */
|
||||
int32_t framedepth; /* Current frame depth. */
|
||||
int32_t retdepth; /* Return frame depth (count of RETF). */
|
||||
|
||||
TValue ksimd[LJ_KSIMD__MAX*2+1]; /* 16 byte aligned SIMD constants. */
|
||||
TValue k64[LJ_K64__MAX]; /* Common 8 byte constants used by backends. */
|
||||
uint32_t k32[LJ_K32__MAX]; /* Ditto for 4 byte constants. */
|
||||
|
||||
IRIns *irbuf; /* Temp. IR instruction buffer. Biased with REF_BIAS. */
|
||||
IRRef irtoplim; /* Upper limit of instuction buffer (biased). */
|
||||
IRRef irbotlim; /* Lower limit of instuction buffer (biased). */
|
||||
IRRef loopref; /* Last loop reference or ref of final LOOP (or 0). */
|
||||
|
||||
MSize sizesnap; /* Size of temp. snapshot buffer. */
|
||||
SnapShot *snapbuf; /* Temp. snapshot buffer. */
|
||||
SnapEntry *snapmapbuf; /* Temp. snapshot map buffer. */
|
||||
MSize sizesnapmap; /* Size of temp. snapshot map buffer. */
|
||||
|
||||
PostProc postproc; /* Required post-processing after execution. */
|
||||
#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
|
||||
uint8_t needsplit; /* Need SPLIT pass. */
|
||||
#endif
|
||||
uint8_t retryrec; /* Retry recording. */
|
||||
|
||||
GCRef *trace; /* Array of traces. */
|
||||
TraceNo freetrace; /* Start of scan for next free trace. */
|
||||
MSize sizetrace; /* Size of trace array. */
|
||||
IRRef1 ktrace; /* Reference to KGC with GCtrace. */
|
||||
|
||||
IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */
|
||||
TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */
|
||||
|
||||
int32_t param[JIT_P__MAX]; /* JIT engine parameters. */
|
||||
|
||||
MCode *exitstubgroup[LJ_MAX_EXITSTUBGR]; /* Exit stub group addresses. */
|
||||
|
||||
HotPenalty penalty[PENALTY_SLOTS]; /* Penalty slots. */
|
||||
uint32_t penaltyslot; /* Round-robin index into penalty slots. */
|
||||
uint32_t prngstate; /* PRNG state. */
|
||||
|
||||
#ifdef LUAJIT_ENABLE_TABLE_BUMP
|
||||
RBCHashEntry rbchash[RBCHASH_SLOTS]; /* Reverse bytecode map. */
|
||||
#endif
|
||||
|
||||
BPropEntry bpropcache[BPROP_SLOTS]; /* Backpropagation cache slots. */
|
||||
uint32_t bpropslot; /* Round-robin index into bpropcache slots. */
|
||||
|
||||
ScEvEntry scev; /* Scalar evolution analysis cache slots. */
|
||||
|
||||
const BCIns *startpc; /* Bytecode PC of starting instruction. */
|
||||
TraceNo parent; /* Parent of current side trace (0 for root traces). */
|
||||
ExitNo exitno; /* Exit number in parent of current side trace. */
|
||||
|
||||
BCIns *patchpc; /* PC for pending re-patch. */
|
||||
BCIns patchins; /* Instruction for pending re-patch. */
|
||||
|
||||
int mcprot; /* Protection of current mcode area. */
|
||||
MCode *mcarea; /* Base of current mcode area. */
|
||||
MCode *mctop; /* Top of current mcode area. */
|
||||
MCode *mcbot; /* Bottom of current mcode area. */
|
||||
size_t szmcarea; /* Size of current mcode area. */
|
||||
size_t szallmcarea; /* Total size of all allocated mcode areas. */
|
||||
|
||||
TValue errinfo; /* Additional info element for trace errors. */
|
||||
|
||||
#if LJ_HASPROFILE
|
||||
GCproto *prev_pt; /* Previous prototype. */
|
||||
BCLine prev_line; /* Previous line. */
|
||||
int prof_mode; /* Profiling mode: 0, 'f', 'l'. */
|
||||
#endif
|
||||
}
|
||||
#if LJ_TARGET_ARM
|
||||
LJ_ALIGN(16) /* For DISPATCH-relative addresses in assembler part. */
|
||||
#endif
|
||||
jit_State;
|
||||
|
||||
/* Trivial PRNG e.g. used for penalty randomization. */
|
||||
static LJ_AINLINE uint32_t LJ_PRNG_BITS(jit_State *J, int bits)
|
||||
{
|
||||
/* Yes, this LCG is very weak, but that doesn't matter for our use case. */
|
||||
J->prngstate = J->prngstate * 1103515245 + 12345;
|
||||
return J->prngstate >> (32-bits);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
** Lexical analyzer.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_LEX_H
|
||||
#define _LJ_LEX_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_err.h"
|
||||
|
||||
/* Lua lexer tokens. */
|
||||
#define TKDEF(_, __) \
|
||||
_(and) _(break) _(do) _(else) _(elseif) _(end) _(false) \
|
||||
_(for) _(function) _(goto) _(if) _(in) _(local) _(nil) _(not) _(or) \
|
||||
_(repeat) _(return) _(then) _(true) _(until) _(while) \
|
||||
__(concat, ..) __(dots, ...) __(eq, ==) __(ge, >=) __(le, <=) __(ne, ~=) \
|
||||
__(label, ::) __(number, <number>) __(name, <name>) __(string, <string>) \
|
||||
__(eof, <eof>)
|
||||
|
||||
enum {
|
||||
TK_OFS = 256,
|
||||
#define TKENUM1(name) TK_##name,
|
||||
#define TKENUM2(name, sym) TK_##name,
|
||||
TKDEF(TKENUM1, TKENUM2)
|
||||
#undef TKENUM1
|
||||
#undef TKENUM2
|
||||
TK_RESERVED = TK_while - TK_OFS
|
||||
};
|
||||
|
||||
typedef int LexChar; /* Lexical character. Unsigned ext. from char. */
|
||||
typedef int LexToken; /* Lexical token. */
|
||||
|
||||
/* Combined bytecode ins/line. Only used during bytecode generation. */
|
||||
typedef struct BCInsLine {
|
||||
BCIns ins; /* Bytecode instruction. */
|
||||
BCLine line; /* Line number for this bytecode. */
|
||||
} BCInsLine;
|
||||
|
||||
/* Info for local variables. Only used during bytecode generation. */
|
||||
typedef struct VarInfo {
|
||||
GCRef name; /* Local variable name or goto/label name. */
|
||||
BCPos startpc; /* First point where the local variable is active. */
|
||||
BCPos endpc; /* First point where the local variable is dead. */
|
||||
uint8_t slot; /* Variable slot. */
|
||||
uint8_t info; /* Variable/goto/label info. */
|
||||
} VarInfo;
|
||||
|
||||
/* Lua lexer state. */
|
||||
typedef struct LexState {
|
||||
struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */
|
||||
struct lua_State *L; /* Lua state. */
|
||||
TValue tokval; /* Current token value. */
|
||||
TValue lookaheadval; /* Lookahead token value. */
|
||||
const char *p; /* Current position in input buffer. */
|
||||
const char *pe; /* End of input buffer. */
|
||||
LexChar c; /* Current character. */
|
||||
LexToken tok; /* Current token. */
|
||||
LexToken lookahead; /* Lookahead token. */
|
||||
SBuf sb; /* String buffer for tokens. */
|
||||
lua_Reader rfunc; /* Reader callback. */
|
||||
void *rdata; /* Reader callback data. */
|
||||
BCLine linenumber; /* Input line counter. */
|
||||
BCLine lastline; /* Line of last token. */
|
||||
GCstr *chunkname; /* Current chunk name (interned string). */
|
||||
const char *chunkarg; /* Chunk name argument. */
|
||||
const char *mode; /* Allow loading bytecode (b) and/or source text (t). */
|
||||
VarInfo *vstack; /* Stack for names and extents of local variables. */
|
||||
MSize sizevstack; /* Size of variable stack. */
|
||||
MSize vtop; /* Top of variable stack. */
|
||||
BCInsLine *bcstack; /* Stack for bytecode instructions/line numbers. */
|
||||
MSize sizebcstack; /* Size of bytecode stack. */
|
||||
uint32_t level; /* Syntactical nesting level. */
|
||||
} LexState;
|
||||
|
||||
LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
|
||||
LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls);
|
||||
LJ_FUNC void lj_lex_next(LexState *ls);
|
||||
LJ_FUNC LexToken lj_lex_lookahead(LexState *ls);
|
||||
LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken tok);
|
||||
LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...);
|
||||
LJ_FUNC void lj_lex_init(lua_State *L);
|
||||
|
||||
#endif
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
** Library function support.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_LIB_H
|
||||
#define _LJ_LIB_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/*
|
||||
** A fallback handler is called by the assembler VM if the fast path fails:
|
||||
**
|
||||
** - too few arguments: unrecoverable.
|
||||
** - wrong argument type: recoverable, if coercion succeeds.
|
||||
** - bad argument value: unrecoverable.
|
||||
** - stack overflow: recoverable, if stack reallocation succeeds.
|
||||
** - extra handling: recoverable.
|
||||
**
|
||||
** The unrecoverable cases throw an error with lj_err_arg(), lj_err_argtype(),
|
||||
** lj_err_caller() or lj_err_callermsg().
|
||||
** The recoverable cases return 0 or the number of results + 1.
|
||||
** The assembler VM retries the fast path only if 0 is returned.
|
||||
** This time the fallback must not be called again or it gets stuck in a loop.
|
||||
*/
|
||||
|
||||
/* Return values from fallback handler. */
|
||||
#define FFH_RETRY 0
|
||||
#define FFH_UNREACHABLE FFH_RETRY
|
||||
#define FFH_RES(n) ((n)+1)
|
||||
#define FFH_TAILCALL (-1)
|
||||
|
||||
LJ_FUNC TValue *lj_lib_checkany(lua_State *L, int narg);
|
||||
LJ_FUNC GCstr *lj_lib_checkstr(lua_State *L, int narg);
|
||||
LJ_FUNC GCstr *lj_lib_optstr(lua_State *L, int narg);
|
||||
#if LJ_DUALNUM
|
||||
LJ_FUNC void lj_lib_checknumber(lua_State *L, int narg);
|
||||
#else
|
||||
#define lj_lib_checknumber(L, narg) lj_lib_checknum((L), (narg))
|
||||
#endif
|
||||
LJ_FUNC lua_Number lj_lib_checknum(lua_State *L, int narg);
|
||||
LJ_FUNC int32_t lj_lib_checkint(lua_State *L, int narg);
|
||||
LJ_FUNC int32_t lj_lib_optint(lua_State *L, int narg, int32_t def);
|
||||
LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg);
|
||||
LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
|
||||
LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
|
||||
LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
|
||||
|
||||
/* Avoid including lj_frame.h. */
|
||||
#if LJ_GC64
|
||||
#define lj_lib_upvalue(L, n) \
|
||||
(&gcval(L->base-2)->fn.c.upvalue[(n)-1])
|
||||
#elif LJ_FR2
|
||||
#define lj_lib_upvalue(L, n) \
|
||||
(&gcref((L->base-2)->gcr)->fn.c.upvalue[(n)-1])
|
||||
#else
|
||||
#define lj_lib_upvalue(L, n) \
|
||||
(&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
|
||||
#endif
|
||||
|
||||
#if LJ_TARGET_WINDOWS
|
||||
#define lj_lib_checkfpu(L) \
|
||||
do { setnumV(L->top++, (lua_Number)1437217655); \
|
||||
if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \
|
||||
L->top--; } while (0)
|
||||
#else
|
||||
#define lj_lib_checkfpu(L) UNUSED(L)
|
||||
#endif
|
||||
|
||||
LJ_FUNC GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n);
|
||||
#define lj_lib_pushcf(L, fn, id) (lj_lib_pushcc(L, (fn), (id), 0))
|
||||
|
||||
/* Library function declarations. Scanned by buildvm. */
|
||||
#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
|
||||
#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
|
||||
#define LJLIB_ASM_(name)
|
||||
#define LJLIB_LUA(name)
|
||||
#define LJLIB_SET(name)
|
||||
#define LJLIB_PUSH(arg)
|
||||
#define LJLIB_REC(handler)
|
||||
#define LJLIB_NOREGUV
|
||||
#define LJLIB_NOREG
|
||||
|
||||
#define LJ_LIB_REG(L, regname, name) \
|
||||
lj_lib_register(L, regname, lj_lib_init_##name, lj_lib_cf_##name)
|
||||
|
||||
LJ_FUNC void lj_lib_register(lua_State *L, const char *libname,
|
||||
const uint8_t *init, const lua_CFunction *cf);
|
||||
LJ_FUNC void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f,
|
||||
GCtab *env);
|
||||
LJ_FUNC int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id,
|
||||
const char *name);
|
||||
|
||||
/* Library init data tags. */
|
||||
#define LIBINIT_LENMASK 0x3f
|
||||
#define LIBINIT_TAGMASK 0xc0
|
||||
#define LIBINIT_CF 0x00
|
||||
#define LIBINIT_ASM 0x40
|
||||
#define LIBINIT_ASM_ 0x80
|
||||
#define LIBINIT_STRING 0xc0
|
||||
#define LIBINIT_MAXSTR 0x38
|
||||
#define LIBINIT_LUA 0xf9
|
||||
#define LIBINIT_SET 0xfa
|
||||
#define LIBINIT_NUMBER 0xfb
|
||||
#define LIBINIT_COPY 0xfc
|
||||
#define LIBINIT_LASTCL 0xfd
|
||||
#define LIBINIT_FFID 0xfe
|
||||
#define LIBINIT_END 0xff
|
||||
|
||||
/* Exported library functions. */
|
||||
|
||||
typedef struct RandomState RandomState;
|
||||
LJ_FUNC uint64_t LJ_FASTCALL lj_math_random_step(RandomState *rs);
|
||||
|
||||
#endif
|
||||
@@ -1,420 +0,0 @@
|
||||
/* This is a generated file. DO NOT EDIT! */
|
||||
|
||||
#ifdef LJLIB_MODULE_base
|
||||
#undef LJLIB_MODULE_base
|
||||
static const lua_CFunction lj_lib_cf_base[] = {
|
||||
lj_ffh_assert,
|
||||
lj_ffh_next,
|
||||
lj_ffh_pairs,
|
||||
lj_ffh_ipairs_aux,
|
||||
lj_ffh_ipairs,
|
||||
lj_ffh_setmetatable,
|
||||
lj_cf_getfenv,
|
||||
lj_cf_setfenv,
|
||||
lj_ffh_rawget,
|
||||
lj_cf_rawset,
|
||||
lj_cf_rawequal,
|
||||
lj_cf_unpack,
|
||||
lj_cf_select,
|
||||
lj_ffh_tonumber,
|
||||
lj_ffh_tostring,
|
||||
lj_cf_error,
|
||||
lj_ffh_pcall,
|
||||
lj_cf_loadfile,
|
||||
lj_cf_load,
|
||||
lj_cf_loadstring,
|
||||
lj_cf_dofile,
|
||||
lj_cf_gcinfo,
|
||||
lj_cf_collectgarbage,
|
||||
lj_cf_newproxy,
|
||||
lj_cf_print
|
||||
};
|
||||
static const uint8_t lj_lib_init_base[] = {
|
||||
2,0,28,70,97,115,115,101,114,116,195,110,105,108,199,98,111,111,108,101,97,
|
||||
110,252,1,200,117,115,101,114,100,97,116,97,198,115,116,114,105,110,103,197,
|
||||
117,112,118,97,108,198,116,104,114,101,97,100,197,112,114,111,116,111,200,102,
|
||||
117,110,99,116,105,111,110,197,116,114,97,99,101,197,99,100,97,116,97,197,116,
|
||||
97,98,108,101,252,9,198,110,117,109,98,101,114,132,116,121,112,101,68,110,101,
|
||||
120,116,253,69,112,97,105,114,115,64,253,70,105,112,97,105,114,115,140,103,
|
||||
101,116,109,101,116,97,116,97,98,108,101,76,115,101,116,109,101,116,97,116,
|
||||
97,98,108,101,7,103,101,116,102,101,110,118,7,115,101,116,102,101,110,118,70,
|
||||
114,97,119,103,101,116,6,114,97,119,115,101,116,8,114,97,119,101,113,117,97,
|
||||
108,6,117,110,112,97,99,107,6,115,101,108,101,99,116,72,116,111,110,117,109,
|
||||
98,101,114,72,116,111,115,116,114,105,110,103,5,101,114,114,111,114,69,112,
|
||||
99,97,108,108,134,120,112,99,97,108,108,8,108,111,97,100,102,105,108,101,4,
|
||||
108,111,97,100,10,108,111,97,100,115,116,114,105,110,103,6,100,111,102,105,
|
||||
108,101,6,103,99,105,110,102,111,14,99,111,108,108,101,99,116,103,97,114,98,
|
||||
97,103,101,252,2,8,110,101,119,112,114,111,120,121,200,116,111,115,116,114,
|
||||
105,110,103,5,112,114,105,110,116,252,3,200,95,86,69,82,83,73,79,78,250,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_coroutine
|
||||
#undef LJLIB_MODULE_coroutine
|
||||
static const lua_CFunction lj_lib_cf_coroutine[] = {
|
||||
lj_cf_coroutine_status,
|
||||
lj_cf_coroutine_running,
|
||||
lj_cf_coroutine_isyieldable,
|
||||
lj_cf_coroutine_create,
|
||||
lj_ffh_coroutine_yield,
|
||||
lj_ffh_coroutine_resume,
|
||||
lj_cf_coroutine_wrap
|
||||
};
|
||||
static const uint8_t lj_lib_init_coroutine[] = {
|
||||
30,13,7,6,115,116,97,116,117,115,7,114,117,110,110,105,110,103,11,105,115,121,
|
||||
105,101,108,100,97,98,108,101,6,99,114,101,97,116,101,69,121,105,101,108,100,
|
||||
70,114,101,115,117,109,101,254,4,119,114,97,112,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_math
|
||||
#undef LJLIB_MODULE_math
|
||||
static const lua_CFunction lj_lib_cf_math[] = {
|
||||
lj_ffh_math_abs,
|
||||
lj_ffh_math_sqrt,
|
||||
lj_ffh_math_log,
|
||||
lj_ffh_math_atan2,
|
||||
lj_ffh_math_ldexp,
|
||||
lj_ffh_math_min,
|
||||
lj_cf_math_random,
|
||||
lj_cf_math_randomseed
|
||||
};
|
||||
static const uint8_t lj_lib_init_math[] = {
|
||||
38,16,30,67,97,98,115,133,102,108,111,111,114,132,99,101,105,108,68,115,113,
|
||||
114,116,133,108,111,103,49,48,131,101,120,112,131,115,105,110,131,99,111,115,
|
||||
131,116,97,110,132,97,115,105,110,132,97,99,111,115,132,97,116,97,110,132,115,
|
||||
105,110,104,132,99,111,115,104,132,116,97,110,104,133,102,114,101,120,112,132,
|
||||
109,111,100,102,67,108,111,103,249,3,100,101,103,0,1,2,0,0,1,2,24,1,0,0,76,
|
||||
1,2,0,241,135,158,166,3,220,203,178,130,4,249,3,114,97,100,0,1,2,0,0,1,2,24,
|
||||
1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,69,97,116,97,110,50,131,
|
||||
112,111,119,132,102,109,111,100,69,108,100,101,120,112,67,109,105,110,131,109,
|
||||
97,120,251,24,45,68,84,251,33,9,64,194,112,105,250,251,0,0,0,0,0,0,240,127,
|
||||
196,104,117,103,101,250,252,2,6,114,97,110,100,111,109,252,2,10,114,97,110,
|
||||
100,111,109,115,101,101,100,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_bit
|
||||
#undef LJLIB_MODULE_bit
|
||||
static const lua_CFunction lj_lib_cf_bit[] = {
|
||||
lj_ffh_bit_tobit,
|
||||
lj_ffh_bit_bnot,
|
||||
lj_ffh_bit_bswap,
|
||||
lj_ffh_bit_lshift,
|
||||
lj_ffh_bit_band,
|
||||
lj_cf_bit_tohex
|
||||
};
|
||||
static const uint8_t lj_lib_init_bit[] = {
|
||||
64,40,12,69,116,111,98,105,116,68,98,110,111,116,69,98,115,119,97,112,70,108,
|
||||
115,104,105,102,116,134,114,115,104,105,102,116,135,97,114,115,104,105,102,
|
||||
116,131,114,111,108,131,114,111,114,68,98,97,110,100,131,98,111,114,132,98,
|
||||
120,111,114,5,116,111,104,101,120,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_string
|
||||
#undef LJLIB_MODULE_string
|
||||
static const lua_CFunction lj_lib_cf_string[] = {
|
||||
lj_ffh_string_byte,
|
||||
lj_ffh_string_char,
|
||||
lj_ffh_string_sub,
|
||||
lj_cf_string_rep,
|
||||
lj_ffh_string_reverse,
|
||||
lj_cf_string_dump,
|
||||
lj_cf_string_find,
|
||||
lj_cf_string_match,
|
||||
lj_cf_string_gmatch,
|
||||
lj_cf_string_gsub,
|
||||
lj_cf_string_format
|
||||
};
|
||||
static const uint8_t lj_lib_init_string[] = {
|
||||
76,51,14,249,3,108,101,110,0,1,2,0,0,0,3,16,0,5,0,21,1,0,0,76,1,2,0,68,98,121,
|
||||
116,101,68,99,104,97,114,67,115,117,98,3,114,101,112,71,114,101,118,101,114,
|
||||
115,101,133,108,111,119,101,114,133,117,112,112,101,114,4,100,117,109,112,4,
|
||||
102,105,110,100,5,109,97,116,99,104,254,6,103,109,97,116,99,104,4,103,115,117,
|
||||
98,6,102,111,114,109,97,116,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_table
|
||||
#undef LJLIB_MODULE_table
|
||||
static const lua_CFunction lj_lib_cf_table[] = {
|
||||
lj_cf_table_maxn,
|
||||
lj_cf_table_insert,
|
||||
lj_cf_table_concat,
|
||||
lj_cf_table_sort
|
||||
};
|
||||
static const uint8_t lj_lib_init_table[] = {
|
||||
90,57,9,249,8,102,111,114,101,97,99,104,105,0,2,9,0,0,0,15,16,0,12,0,16,1,9,
|
||||
0,41,2,1,0,21,3,0,0,41,4,1,0,77,2,8,128,18,6,1,0,18,7,5,0,59,8,5,0,66,6,3,2,
|
||||
10,6,0,0,88,7,1,128,76,6,2,0,79,2,248,127,75,0,1,0,249,7,102,111,114,101,97,
|
||||
99,104,0,2,10,0,0,0,16,16,0,12,0,16,1,9,0,43,2,0,0,18,3,0,0,41,4,0,0,88,5,7,
|
||||
128,18,7,1,0,18,8,5,0,18,9,6,0,66,7,3,2,10,7,0,0,88,8,1,128,76,7,2,0,70,5,3,
|
||||
3,82,5,247,127,75,0,1,0,249,4,103,101,116,110,0,1,2,0,0,0,3,16,0,12,0,21,1,
|
||||
0,0,76,1,2,0,4,109,97,120,110,6,105,110,115,101,114,116,249,6,114,101,109,111,
|
||||
118,101,0,2,10,0,0,2,30,16,0,12,0,21,2,0,0,11,1,0,0,88,3,7,128,8,2,0,0,88,3,
|
||||
23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,17,1,15,0,41,3,1,0,3,
|
||||
3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2,0,41,6,1,0,77,
|
||||
4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4,2,0,76,3,2,0,
|
||||
75,0,1,0,0,2,249,4,109,111,118,101,0,5,12,0,0,0,35,16,0,12,0,17,1,15,0,17,2,
|
||||
15,0,17,3,15,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,
|
||||
5,1,3,0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,
|
||||
7,2,0,41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,
|
||||
8,128,18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,
|
||||
4,79,6,252,127,76,4,2,0,6,99,111,110,99,97,116,4,115,111,114,116,254,254,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_io_method
|
||||
#undef LJLIB_MODULE_io_method
|
||||
static const lua_CFunction lj_lib_cf_io_method[] = {
|
||||
lj_cf_io_method_close,
|
||||
lj_cf_io_method_read,
|
||||
lj_cf_io_method_write,
|
||||
lj_cf_io_method_flush,
|
||||
lj_cf_io_method_seek,
|
||||
lj_cf_io_method_setvbuf,
|
||||
lj_cf_io_method_lines,
|
||||
lj_cf_io_method___gc,
|
||||
lj_cf_io_method___tostring
|
||||
};
|
||||
static const uint8_t lj_lib_init_io_method[] = {
|
||||
96,57,10,5,99,108,111,115,101,4,114,101,97,100,5,119,114,105,116,101,5,102,
|
||||
108,117,115,104,4,115,101,101,107,7,115,101,116,118,98,117,102,5,108,105,110,
|
||||
101,115,4,95,95,103,99,10,95,95,116,111,115,116,114,105,110,103,252,1,199,95,
|
||||
95,105,110,100,101,120,250,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_io
|
||||
#undef LJLIB_MODULE_io
|
||||
static const lua_CFunction lj_lib_cf_io[] = {
|
||||
lj_cf_io_open,
|
||||
lj_cf_io_popen,
|
||||
lj_cf_io_tmpfile,
|
||||
lj_cf_io_close,
|
||||
lj_cf_io_read,
|
||||
lj_cf_io_write,
|
||||
lj_cf_io_flush,
|
||||
lj_cf_io_input,
|
||||
lj_cf_io_output,
|
||||
lj_cf_io_lines,
|
||||
lj_cf_io_type
|
||||
};
|
||||
static const uint8_t lj_lib_init_io[] = {
|
||||
105,57,12,252,2,192,250,4,111,112,101,110,5,112,111,112,101,110,7,116,109,112,
|
||||
102,105,108,101,5,99,108,111,115,101,4,114,101,97,100,5,119,114,105,116,101,
|
||||
5,102,108,117,115,104,5,105,110,112,117,116,6,111,117,116,112,117,116,5,108,
|
||||
105,110,101,115,4,116,121,112,101,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_os
|
||||
#undef LJLIB_MODULE_os
|
||||
static const lua_CFunction lj_lib_cf_os[] = {
|
||||
lj_cf_os_execute,
|
||||
lj_cf_os_remove,
|
||||
lj_cf_os_rename,
|
||||
lj_cf_os_tmpname,
|
||||
lj_cf_os_getenv,
|
||||
lj_cf_os_exit,
|
||||
lj_cf_os_clock,
|
||||
lj_cf_os_date,
|
||||
lj_cf_os_time,
|
||||
lj_cf_os_difftime,
|
||||
lj_cf_os_setlocale
|
||||
};
|
||||
static const uint8_t lj_lib_init_os[] = {
|
||||
116,57,11,7,101,120,101,99,117,116,101,6,114,101,109,111,118,101,6,114,101,
|
||||
110,97,109,101,7,116,109,112,110,97,109,101,6,103,101,116,101,110,118,4,101,
|
||||
120,105,116,5,99,108,111,99,107,4,100,97,116,101,4,116,105,109,101,8,100,105,
|
||||
102,102,116,105,109,101,9,115,101,116,108,111,99,97,108,101,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_debug
|
||||
#undef LJLIB_MODULE_debug
|
||||
static const lua_CFunction lj_lib_cf_debug[] = {
|
||||
lj_cf_debug_getregistry,
|
||||
lj_cf_debug_getmetatable,
|
||||
lj_cf_debug_setmetatable,
|
||||
lj_cf_debug_getfenv,
|
||||
lj_cf_debug_setfenv,
|
||||
lj_cf_debug_getinfo,
|
||||
lj_cf_debug_getlocal,
|
||||
lj_cf_debug_setlocal,
|
||||
lj_cf_debug_getupvalue,
|
||||
lj_cf_debug_setupvalue,
|
||||
lj_cf_debug_upvalueid,
|
||||
lj_cf_debug_upvaluejoin,
|
||||
lj_cf_debug_sethook,
|
||||
lj_cf_debug_gethook,
|
||||
lj_cf_debug_debug,
|
||||
lj_cf_debug_traceback
|
||||
};
|
||||
static const uint8_t lj_lib_init_debug[] = {
|
||||
127,57,16,11,103,101,116,114,101,103,105,115,116,114,121,12,103,101,116,109,
|
||||
101,116,97,116,97,98,108,101,12,115,101,116,109,101,116,97,116,97,98,108,101,
|
||||
7,103,101,116,102,101,110,118,7,115,101,116,102,101,110,118,7,103,101,116,105,
|
||||
110,102,111,8,103,101,116,108,111,99,97,108,8,115,101,116,108,111,99,97,108,
|
||||
10,103,101,116,117,112,118,97,108,117,101,10,115,101,116,117,112,118,97,108,
|
||||
117,101,9,117,112,118,97,108,117,101,105,100,11,117,112,118,97,108,117,101,
|
||||
106,111,105,110,7,115,101,116,104,111,111,107,7,103,101,116,104,111,111,107,
|
||||
5,100,101,98,117,103,9,116,114,97,99,101,98,97,99,107,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_jit
|
||||
#undef LJLIB_MODULE_jit
|
||||
static const lua_CFunction lj_lib_cf_jit[] = {
|
||||
lj_cf_jit_on,
|
||||
lj_cf_jit_off,
|
||||
lj_cf_jit_flush,
|
||||
lj_cf_jit_status,
|
||||
lj_cf_jit_attach
|
||||
};
|
||||
static const uint8_t lj_lib_init_jit[] = {
|
||||
143,57,9,2,111,110,3,111,102,102,5,102,108,117,115,104,6,115,116,97,116,117,
|
||||
115,6,97,116,116,97,99,104,252,5,194,111,115,250,252,4,196,97,114,99,104,250,
|
||||
252,3,203,118,101,114,115,105,111,110,95,110,117,109,250,252,2,199,118,101,
|
||||
114,115,105,111,110,250,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_jit_util
|
||||
#undef LJLIB_MODULE_jit_util
|
||||
static const lua_CFunction lj_lib_cf_jit_util[] = {
|
||||
lj_cf_jit_util_funcinfo,
|
||||
lj_cf_jit_util_funcbc,
|
||||
lj_cf_jit_util_funck,
|
||||
lj_cf_jit_util_funcuvname,
|
||||
lj_cf_jit_util_traceinfo,
|
||||
lj_cf_jit_util_traceir,
|
||||
lj_cf_jit_util_tracek,
|
||||
lj_cf_jit_util_tracesnap,
|
||||
lj_cf_jit_util_tracemc,
|
||||
lj_cf_jit_util_traceexitstub,
|
||||
lj_cf_jit_util_ircalladdr
|
||||
};
|
||||
static const uint8_t lj_lib_init_jit_util[] = {
|
||||
148,57,11,8,102,117,110,99,105,110,102,111,6,102,117,110,99,98,99,5,102,117,
|
||||
110,99,107,10,102,117,110,99,117,118,110,97,109,101,9,116,114,97,99,101,105,
|
||||
110,102,111,7,116,114,97,99,101,105,114,6,116,114,97,99,101,107,9,116,114,97,
|
||||
99,101,115,110,97,112,7,116,114,97,99,101,109,99,13,116,114,97,99,101,101,120,
|
||||
105,116,115,116,117,98,10,105,114,99,97,108,108,97,100,100,114,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_jit_opt
|
||||
#undef LJLIB_MODULE_jit_opt
|
||||
static const lua_CFunction lj_lib_cf_jit_opt[] = {
|
||||
lj_cf_jit_opt_start
|
||||
};
|
||||
static const uint8_t lj_lib_init_jit_opt[] = {
|
||||
159,57,1,5,115,116,97,114,116,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_jit_profile
|
||||
#undef LJLIB_MODULE_jit_profile
|
||||
static const lua_CFunction lj_lib_cf_jit_profile[] = {
|
||||
lj_cf_jit_profile_start,
|
||||
lj_cf_jit_profile_stop,
|
||||
lj_cf_jit_profile_dumpstack
|
||||
};
|
||||
static const uint8_t lj_lib_init_jit_profile[] = {
|
||||
160,57,3,5,115,116,97,114,116,4,115,116,111,112,9,100,117,109,112,115,116,97,
|
||||
99,107,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_ffi_meta
|
||||
#undef LJLIB_MODULE_ffi_meta
|
||||
static const lua_CFunction lj_lib_cf_ffi_meta[] = {
|
||||
lj_cf_ffi_meta___index,
|
||||
lj_cf_ffi_meta___newindex,
|
||||
lj_cf_ffi_meta___eq,
|
||||
lj_cf_ffi_meta___len,
|
||||
lj_cf_ffi_meta___lt,
|
||||
lj_cf_ffi_meta___le,
|
||||
lj_cf_ffi_meta___concat,
|
||||
lj_cf_ffi_meta___call,
|
||||
lj_cf_ffi_meta___add,
|
||||
lj_cf_ffi_meta___sub,
|
||||
lj_cf_ffi_meta___mul,
|
||||
lj_cf_ffi_meta___div,
|
||||
lj_cf_ffi_meta___mod,
|
||||
lj_cf_ffi_meta___pow,
|
||||
lj_cf_ffi_meta___unm,
|
||||
lj_cf_ffi_meta___tostring,
|
||||
lj_cf_ffi_meta___pairs,
|
||||
lj_cf_ffi_meta___ipairs
|
||||
};
|
||||
static const uint8_t lj_lib_init_ffi_meta[] = {
|
||||
163,57,19,7,95,95,105,110,100,101,120,10,95,95,110,101,119,105,110,100,101,
|
||||
120,4,95,95,101,113,5,95,95,108,101,110,4,95,95,108,116,4,95,95,108,101,8,95,
|
||||
95,99,111,110,99,97,116,6,95,95,99,97,108,108,5,95,95,97,100,100,5,95,95,115,
|
||||
117,98,5,95,95,109,117,108,5,95,95,100,105,118,5,95,95,109,111,100,5,95,95,
|
||||
112,111,119,5,95,95,117,110,109,10,95,95,116,111,115,116,114,105,110,103,7,
|
||||
95,95,112,97,105,114,115,8,95,95,105,112,97,105,114,115,195,102,102,105,203,
|
||||
95,95,109,101,116,97,116,97,98,108,101,250,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_ffi_clib
|
||||
#undef LJLIB_MODULE_ffi_clib
|
||||
static const lua_CFunction lj_lib_cf_ffi_clib[] = {
|
||||
lj_cf_ffi_clib___index,
|
||||
lj_cf_ffi_clib___newindex,
|
||||
lj_cf_ffi_clib___gc
|
||||
};
|
||||
static const uint8_t lj_lib_init_ffi_clib[] = {
|
||||
181,57,3,7,95,95,105,110,100,101,120,10,95,95,110,101,119,105,110,100,101,120,
|
||||
4,95,95,103,99,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_ffi_callback
|
||||
#undef LJLIB_MODULE_ffi_callback
|
||||
static const lua_CFunction lj_lib_cf_ffi_callback[] = {
|
||||
lj_cf_ffi_callback_free,
|
||||
lj_cf_ffi_callback_set
|
||||
};
|
||||
static const uint8_t lj_lib_init_ffi_callback[] = {
|
||||
184,57,3,4,102,114,101,101,3,115,101,116,252,1,199,95,95,105,110,100,101,120,
|
||||
250,255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LJLIB_MODULE_ffi
|
||||
#undef LJLIB_MODULE_ffi
|
||||
static const lua_CFunction lj_lib_cf_ffi[] = {
|
||||
lj_cf_ffi_cdef,
|
||||
lj_cf_ffi_new,
|
||||
lj_cf_ffi_cast,
|
||||
lj_cf_ffi_typeof,
|
||||
lj_cf_ffi_typeinfo,
|
||||
lj_cf_ffi_istype,
|
||||
lj_cf_ffi_sizeof,
|
||||
lj_cf_ffi_alignof,
|
||||
lj_cf_ffi_offsetof,
|
||||
lj_cf_ffi_errno,
|
||||
lj_cf_ffi_string,
|
||||
lj_cf_ffi_copy,
|
||||
lj_cf_ffi_fill,
|
||||
lj_cf_ffi_abi,
|
||||
lj_cf_ffi_metatype,
|
||||
lj_cf_ffi_gc,
|
||||
lj_cf_ffi_load
|
||||
};
|
||||
static const uint8_t lj_lib_init_ffi[] = {
|
||||
186,57,23,4,99,100,101,102,3,110,101,119,4,99,97,115,116,6,116,121,112,101,
|
||||
111,102,8,116,121,112,101,105,110,102,111,6,105,115,116,121,112,101,6,115,105,
|
||||
122,101,111,102,7,97,108,105,103,110,111,102,8,111,102,102,115,101,116,111,
|
||||
102,5,101,114,114,110,111,6,115,116,114,105,110,103,4,99,111,112,121,4,102,
|
||||
105,108,108,3,97,98,105,252,8,192,250,8,109,101,116,97,116,121,112,101,252,
|
||||
7,192,250,2,103,99,252,5,192,250,4,108,111,97,100,252,4,193,67,250,252,3,194,
|
||||
111,115,250,252,2,196,97,114,99,104,250,255
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
** Machine code management.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_MCODE_H
|
||||
#define _LJ_MCODE_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
#if LJ_HASJIT || LJ_HASFFI
|
||||
LJ_FUNC void lj_mcode_sync(void *start, void *end);
|
||||
#endif
|
||||
|
||||
#if LJ_HASJIT
|
||||
|
||||
#include "lj_jit.h"
|
||||
|
||||
LJ_FUNC void lj_mcode_free(jit_State *J);
|
||||
LJ_FUNC MCode *lj_mcode_reserve(jit_State *J, MCode **lim);
|
||||
LJ_FUNC void lj_mcode_commit(jit_State *J, MCode *m);
|
||||
LJ_FUNC void lj_mcode_abort(jit_State *J);
|
||||
LJ_FUNC MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish);
|
||||
LJ_FUNC_NORET void lj_mcode_limiterr(jit_State *J, size_t need);
|
||||
|
||||
#define lj_mcode_commitbot(J, m) (J->mcbot = (m))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
** Metamethod handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_META_H
|
||||
#define _LJ_META_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* Metamethod handling */
|
||||
LJ_FUNC void lj_meta_init(lua_State *L);
|
||||
LJ_FUNC cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name);
|
||||
LJ_FUNC cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC int lj_meta_tailcall(lua_State *L, cTValue *tv);
|
||||
#endif
|
||||
|
||||
#define lj_meta_fastg(g, mt, mm) \
|
||||
((mt) == NULL ? NULL : ((mt)->nomm & (1u<<(mm))) ? NULL : \
|
||||
lj_meta_cache(mt, mm, mmname_str(g, mm)))
|
||||
#define lj_meta_fast(L, mt, mm) lj_meta_fastg(G(L), mt, mm)
|
||||
|
||||
/* C helpers for some instructions, called from assembler VM. */
|
||||
LJ_FUNCA cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k);
|
||||
LJ_FUNCA TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k);
|
||||
LJ_FUNCA TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb,
|
||||
cTValue *rc, BCReg op);
|
||||
LJ_FUNCA TValue *lj_meta_cat(lua_State *L, TValue *top, int left);
|
||||
LJ_FUNCA TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o);
|
||||
LJ_FUNCA TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne);
|
||||
LJ_FUNCA TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins);
|
||||
LJ_FUNCA TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op);
|
||||
LJ_FUNCA void lj_meta_istype(lua_State *L, BCReg ra, BCReg tp);
|
||||
LJ_FUNCA void lj_meta_call(lua_State *L, TValue *func, TValue *top);
|
||||
LJ_FUNCA void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o);
|
||||
|
||||
#endif
|
||||
@@ -1,980 +0,0 @@
|
||||
/*
|
||||
** LuaJIT VM tags, values and objects.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_OBJ_H
|
||||
#define _LJ_OBJ_H
|
||||
|
||||
#include "lua.h"
|
||||
#include "lj_def.h"
|
||||
#include "lj_arch.h"
|
||||
|
||||
/* -- Memory references (32 bit address space) ---------------------------- */
|
||||
|
||||
/* Memory and GC object sizes. */
|
||||
typedef uint32_t MSize;
|
||||
#if LJ_GC64
|
||||
typedef uint64_t GCSize;
|
||||
#else
|
||||
typedef uint32_t GCSize;
|
||||
#endif
|
||||
|
||||
/* Memory reference */
|
||||
typedef struct MRef {
|
||||
#if LJ_GC64
|
||||
uint64_t ptr64; /* True 64 bit pointer. */
|
||||
#else
|
||||
uint32_t ptr32; /* Pseudo 32 bit pointer. */
|
||||
#endif
|
||||
} MRef;
|
||||
|
||||
#if LJ_GC64
|
||||
#define mref(r, t) ((t *)(void *)(r).ptr64)
|
||||
|
||||
#define setmref(r, p) ((r).ptr64 = (uint64_t)(void *)(p))
|
||||
#define setmrefr(r, v) ((r).ptr64 = (v).ptr64)
|
||||
#else
|
||||
#define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32)
|
||||
|
||||
#define setmref(r, p) ((r).ptr32 = (uint32_t)(uintptr_t)(void *)(p))
|
||||
#define setmrefr(r, v) ((r).ptr32 = (v).ptr32)
|
||||
#endif
|
||||
|
||||
/* -- GC object references (32 bit address space) ------------------------- */
|
||||
|
||||
/* GCobj reference */
|
||||
typedef struct GCRef {
|
||||
#if LJ_GC64
|
||||
uint64_t gcptr64; /* True 64 bit pointer. */
|
||||
#else
|
||||
uint32_t gcptr32; /* Pseudo 32 bit pointer. */
|
||||
#endif
|
||||
} GCRef;
|
||||
|
||||
/* Common GC header for all collectable objects. */
|
||||
#define GCHeader GCRef nextgc; uint8_t marked; uint8_t gct
|
||||
/* This occupies 6 bytes, so use the next 2 bytes for non-32 bit fields. */
|
||||
|
||||
#if LJ_GC64
|
||||
#define gcref(r) ((GCobj *)(r).gcptr64)
|
||||
#define gcrefp(r, t) ((t *)(void *)(r).gcptr64)
|
||||
#define gcrefu(r) ((r).gcptr64)
|
||||
#define gcrefeq(r1, r2) ((r1).gcptr64 == (r2).gcptr64)
|
||||
|
||||
#define setgcref(r, gc) ((r).gcptr64 = (uint64_t)&(gc)->gch)
|
||||
#define setgcreft(r, gc, it) \
|
||||
(r).gcptr64 = (uint64_t)&(gc)->gch | (((uint64_t)(it)) << 47)
|
||||
#define setgcrefp(r, p) ((r).gcptr64 = (uint64_t)(p))
|
||||
#define setgcrefnull(r) ((r).gcptr64 = 0)
|
||||
#define setgcrefr(r, v) ((r).gcptr64 = (v).gcptr64)
|
||||
#else
|
||||
#define gcref(r) ((GCobj *)(uintptr_t)(r).gcptr32)
|
||||
#define gcrefp(r, t) ((t *)(void *)(uintptr_t)(r).gcptr32)
|
||||
#define gcrefu(r) ((r).gcptr32)
|
||||
#define gcrefeq(r1, r2) ((r1).gcptr32 == (r2).gcptr32)
|
||||
|
||||
#define setgcref(r, gc) ((r).gcptr32 = (uint32_t)(uintptr_t)&(gc)->gch)
|
||||
#define setgcrefp(r, p) ((r).gcptr32 = (uint32_t)(uintptr_t)(p))
|
||||
#define setgcrefnull(r) ((r).gcptr32 = 0)
|
||||
#define setgcrefr(r, v) ((r).gcptr32 = (v).gcptr32)
|
||||
#endif
|
||||
|
||||
#define gcnext(gc) (gcref((gc)->gch.nextgc))
|
||||
|
||||
/* IMPORTANT NOTE:
|
||||
**
|
||||
** All uses of the setgcref* macros MUST be accompanied with a write barrier.
|
||||
**
|
||||
** This is to ensure the integrity of the incremental GC. The invariant
|
||||
** to preserve is that a black object never points to a white object.
|
||||
** I.e. never store a white object into a field of a black object.
|
||||
**
|
||||
** It's ok to LEAVE OUT the write barrier ONLY in the following cases:
|
||||
** - The source is not a GC object (NULL).
|
||||
** - The target is a GC root. I.e. everything in global_State.
|
||||
** - The target is a lua_State field (threads are never black).
|
||||
** - The target is a stack slot, see setgcV et al.
|
||||
** - The target is an open upvalue, i.e. pointing to a stack slot.
|
||||
** - The target is a newly created object (i.e. marked white). But make
|
||||
** sure nothing invokes the GC inbetween.
|
||||
** - The target and the source are the same object (self-reference).
|
||||
** - The target already contains the object (e.g. moving elements around).
|
||||
**
|
||||
** The most common case is a store to a stack slot. All other cases where
|
||||
** a barrier has been omitted are annotated with a NOBARRIER comment.
|
||||
**
|
||||
** The same logic applies for stores to table slots (array part or hash
|
||||
** part). ALL uses of lj_tab_set* require a barrier for the stored value
|
||||
** *and* the stored key, based on the above rules. In practice this means
|
||||
** a barrier is needed if *either* of the key or value are a GC object.
|
||||
**
|
||||
** It's ok to LEAVE OUT the write barrier in the following special cases:
|
||||
** - The stored value is nil. The key doesn't matter because it's either
|
||||
** not resurrected or lj_tab_newkey() will take care of the key barrier.
|
||||
** - The key doesn't matter if the *previously* stored value is guaranteed
|
||||
** to be non-nil (because the key is kept alive in the table).
|
||||
** - The key doesn't matter if it's guaranteed not to be part of the table,
|
||||
** since lj_tab_newkey() takes care of the key barrier. This applies
|
||||
** trivially to new tables, but watch out for resurrected keys. Storing
|
||||
** a nil value leaves the key in the table!
|
||||
**
|
||||
** In case of doubt use lj_gc_anybarriert() as it's rather cheap. It's used
|
||||
** by the interpreter for all table stores.
|
||||
**
|
||||
** Note: In contrast to Lua's GC, LuaJIT's GC does *not* specially mark
|
||||
** dead keys in tables. The reference is left in, but it's guaranteed to
|
||||
** be never dereferenced as long as the value is nil. It's ok if the key is
|
||||
** freed or if any object subsequently gets the same address.
|
||||
**
|
||||
** Not destroying dead keys helps to keep key hash slots stable. This avoids
|
||||
** specialization back-off for HREFK when a value flips between nil and
|
||||
** non-nil and the GC gets in the way. It also allows safely hoisting
|
||||
** HREF/HREFK across GC steps. Dead keys are only removed if a table is
|
||||
** resized (i.e. by NEWREF) and xREF must not be CSEd across a resize.
|
||||
**
|
||||
** The trade-off is that a write barrier for tables must take the key into
|
||||
** account, too. Implicitly resurrecting the key by storing a non-nil value
|
||||
** may invalidate the incremental GC invariant.
|
||||
*/
|
||||
|
||||
/* -- Common type definitions --------------------------------------------- */
|
||||
|
||||
/* Types for handling bytecodes. Need this here, details in lj_bc.h. */
|
||||
typedef uint32_t BCIns; /* Bytecode instruction. */
|
||||
typedef uint32_t BCPos; /* Bytecode position. */
|
||||
typedef uint32_t BCReg; /* Bytecode register. */
|
||||
typedef int32_t BCLine; /* Bytecode line number. */
|
||||
|
||||
/* Internal assembler functions. Never call these directly from C. */
|
||||
typedef void (*ASMFunction)(void);
|
||||
|
||||
/* Resizable string buffer. Need this here, details in lj_buf.h. */
|
||||
typedef struct SBuf {
|
||||
MRef p; /* String buffer pointer. */
|
||||
MRef e; /* String buffer end pointer. */
|
||||
MRef b; /* String buffer base. */
|
||||
MRef L; /* lua_State, used for buffer resizing. */
|
||||
} SBuf;
|
||||
|
||||
/* -- Tags and values ----------------------------------------------------- */
|
||||
|
||||
/* Frame link. */
|
||||
typedef union {
|
||||
int32_t ftsz; /* Frame type and size of previous frame. */
|
||||
MRef pcr; /* Or PC for Lua frames. */
|
||||
} FrameLink;
|
||||
|
||||
/* Tagged value. */
|
||||
typedef LJ_ALIGN(8) union TValue {
|
||||
uint64_t u64; /* 64 bit pattern overlaps number. */
|
||||
lua_Number n; /* Number object overlaps split tag/value object. */
|
||||
#if LJ_GC64
|
||||
GCRef gcr; /* GCobj reference with tag. */
|
||||
int64_t it64;
|
||||
struct {
|
||||
LJ_ENDIAN_LOHI(
|
||||
int32_t i; /* Integer value. */
|
||||
, uint32_t it; /* Internal object tag. Must overlap MSW of number. */
|
||||
)
|
||||
};
|
||||
#else
|
||||
struct {
|
||||
LJ_ENDIAN_LOHI(
|
||||
union {
|
||||
GCRef gcr; /* GCobj reference (if any). */
|
||||
int32_t i; /* Integer value. */
|
||||
};
|
||||
, uint32_t it; /* Internal object tag. Must overlap MSW of number. */
|
||||
)
|
||||
};
|
||||
#endif
|
||||
#if LJ_FR2
|
||||
int64_t ftsz; /* Frame type and size of previous frame, or PC. */
|
||||
#else
|
||||
struct {
|
||||
LJ_ENDIAN_LOHI(
|
||||
GCRef func; /* Function for next frame (or dummy L). */
|
||||
, FrameLink tp; /* Link to previous frame. */
|
||||
)
|
||||
} fr;
|
||||
#endif
|
||||
struct {
|
||||
LJ_ENDIAN_LOHI(
|
||||
uint32_t lo; /* Lower 32 bits of number. */
|
||||
, uint32_t hi; /* Upper 32 bits of number. */
|
||||
)
|
||||
} u32;
|
||||
} TValue;
|
||||
|
||||
typedef const TValue cTValue;
|
||||
|
||||
#define tvref(r) (mref(r, TValue))
|
||||
|
||||
/* More external and GCobj tags for internal objects. */
|
||||
#define LAST_TT LUA_TTHREAD
|
||||
#define LUA_TPROTO (LAST_TT+1)
|
||||
#define LUA_TCDATA (LAST_TT+2)
|
||||
|
||||
/* Internal object tags.
|
||||
**
|
||||
** Format for 32 bit GC references (!LJ_GC64):
|
||||
**
|
||||
** Internal tags overlap the MSW of a number object (must be a double).
|
||||
** Interpreted as a double these are special NaNs. The FPU only generates
|
||||
** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available
|
||||
** for use as internal tags. Small negative numbers are used to shorten the
|
||||
** encoding of type comparisons (reg/mem against sign-ext. 8 bit immediate).
|
||||
**
|
||||
** ---MSW---.---LSW---
|
||||
** primitive types | itype | |
|
||||
** lightuserdata | itype | void * | (32 bit platforms)
|
||||
** lightuserdata |ffff| void * | (64 bit platforms, 47 bit pointers)
|
||||
** GC objects | itype | GCRef |
|
||||
** int (LJ_DUALNUM)| itype | int |
|
||||
** number -------double------
|
||||
**
|
||||
** Format for 64 bit GC references (LJ_GC64):
|
||||
**
|
||||
** The upper 13 bits must be 1 (0xfff8...) for a special NaN. The next
|
||||
** 4 bits hold the internal tag. The lowest 47 bits either hold a pointer,
|
||||
** a zero-extended 32 bit integer or all bits set to 1 for primitive types.
|
||||
**
|
||||
** ------MSW------.------LSW------
|
||||
** primitive types |1..1|itype|1..................1|
|
||||
** GC objects/lightud |1..1|itype|-------GCRef--------|
|
||||
** int (LJ_DUALNUM) |1..1|itype|0..0|-----int-------|
|
||||
** number ------------double-------------
|
||||
**
|
||||
** ORDER LJ_T
|
||||
** Primitive types nil/false/true must be first, lightuserdata next.
|
||||
** GC objects are at the end, table/userdata must be lowest.
|
||||
** Also check lj_ir.h for similar ordering constraints.
|
||||
*/
|
||||
#define LJ_TNIL (~0u)
|
||||
#define LJ_TFALSE (~1u)
|
||||
#define LJ_TTRUE (~2u)
|
||||
#define LJ_TLIGHTUD (~3u)
|
||||
#define LJ_TSTR (~4u)
|
||||
#define LJ_TUPVAL (~5u)
|
||||
#define LJ_TTHREAD (~6u)
|
||||
#define LJ_TPROTO (~7u)
|
||||
#define LJ_TFUNC (~8u)
|
||||
#define LJ_TTRACE (~9u)
|
||||
#define LJ_TCDATA (~10u)
|
||||
#define LJ_TTAB (~11u)
|
||||
#define LJ_TUDATA (~12u)
|
||||
/* This is just the canonical number type used in some places. */
|
||||
#define LJ_TNUMX (~13u)
|
||||
|
||||
/* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */
|
||||
#if LJ_64 && !LJ_GC64
|
||||
#define LJ_TISNUM 0xfffeffffu
|
||||
#else
|
||||
#define LJ_TISNUM LJ_TNUMX
|
||||
#endif
|
||||
#define LJ_TISTRUECOND LJ_TFALSE
|
||||
#define LJ_TISPRI LJ_TTRUE
|
||||
#define LJ_TISGCV (LJ_TSTR+1)
|
||||
#define LJ_TISTABUD LJ_TTAB
|
||||
|
||||
#if LJ_GC64
|
||||
#define LJ_GCVMASK (((uint64_t)1 << 47) - 1)
|
||||
#endif
|
||||
|
||||
/* -- String object ------------------------------------------------------- */
|
||||
|
||||
/* String object header. String payload follows. */
|
||||
typedef struct GCstr {
|
||||
GCHeader;
|
||||
uint8_t reserved; /* Used by lexer for fast lookup of reserved words. */
|
||||
uint8_t unused;
|
||||
MSize hash; /* Hash of string. */
|
||||
MSize len; /* Size of string. */
|
||||
} GCstr;
|
||||
|
||||
#define strref(r) (&gcref((r))->str)
|
||||
#define strdata(s) ((const char *)((s)+1))
|
||||
#define strdatawr(s) ((char *)((s)+1))
|
||||
#define strVdata(o) strdata(strV(o))
|
||||
#define sizestring(s) (sizeof(struct GCstr)+(s)->len+1)
|
||||
|
||||
/* -- Userdata object ----------------------------------------------------- */
|
||||
|
||||
/* Userdata object. Payload follows. */
|
||||
typedef struct GCudata {
|
||||
GCHeader;
|
||||
uint8_t udtype; /* Userdata type. */
|
||||
uint8_t unused2;
|
||||
GCRef env; /* Should be at same offset in GCfunc. */
|
||||
MSize len; /* Size of payload. */
|
||||
GCRef metatable; /* Must be at same offset in GCtab. */
|
||||
uint32_t align1; /* To force 8 byte alignment of the payload. */
|
||||
} GCudata;
|
||||
|
||||
/* Userdata types. */
|
||||
enum {
|
||||
UDTYPE_USERDATA, /* Regular userdata. */
|
||||
UDTYPE_IO_FILE, /* I/O library FILE. */
|
||||
UDTYPE_FFI_CLIB, /* FFI C library namespace. */
|
||||
UDTYPE__MAX
|
||||
};
|
||||
|
||||
#define uddata(u) ((void *)((u)+1))
|
||||
#define sizeudata(u) (sizeof(struct GCudata)+(u)->len)
|
||||
|
||||
/* -- C data object ------------------------------------------------------- */
|
||||
|
||||
/* C data object. Payload follows. */
|
||||
typedef struct GCcdata {
|
||||
GCHeader;
|
||||
uint16_t ctypeid; /* C type ID. */
|
||||
} GCcdata;
|
||||
|
||||
/* Prepended to variable-sized or realigned C data objects. */
|
||||
typedef struct GCcdataVar {
|
||||
uint16_t offset; /* Offset to allocated memory (relative to GCcdata). */
|
||||
uint16_t extra; /* Extra space allocated (incl. GCcdata + GCcdatav). */
|
||||
MSize len; /* Size of payload. */
|
||||
} GCcdataVar;
|
||||
|
||||
#define cdataptr(cd) ((void *)((cd)+1))
|
||||
#define cdataisv(cd) ((cd)->marked & 0x80)
|
||||
#define cdatav(cd) ((GCcdataVar *)((char *)(cd) - sizeof(GCcdataVar)))
|
||||
#define cdatavlen(cd) check_exp(cdataisv(cd), cdatav(cd)->len)
|
||||
#define sizecdatav(cd) (cdatavlen(cd) + cdatav(cd)->extra)
|
||||
#define memcdatav(cd) ((void *)((char *)(cd) - cdatav(cd)->offset))
|
||||
|
||||
/* -- Prototype object ---------------------------------------------------- */
|
||||
|
||||
#define SCALE_NUM_GCO ((int32_t)sizeof(lua_Number)/sizeof(GCRef))
|
||||
#define round_nkgc(n) (((n) + SCALE_NUM_GCO-1) & ~(SCALE_NUM_GCO-1))
|
||||
|
||||
typedef struct GCproto {
|
||||
GCHeader;
|
||||
uint8_t numparams; /* Number of parameters. */
|
||||
uint8_t framesize; /* Fixed frame size. */
|
||||
MSize sizebc; /* Number of bytecode instructions. */
|
||||
#if LJ_GC64
|
||||
uint32_t unused_gc64;
|
||||
#endif
|
||||
GCRef gclist;
|
||||
MRef k; /* Split constant array (points to the middle). */
|
||||
MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */
|
||||
MSize sizekgc; /* Number of collectable constants. */
|
||||
MSize sizekn; /* Number of lua_Number constants. */
|
||||
MSize sizept; /* Total size including colocated arrays. */
|
||||
uint8_t sizeuv; /* Number of upvalues. */
|
||||
uint8_t flags; /* Miscellaneous flags (see below). */
|
||||
uint16_t trace; /* Anchor for chain of root traces. */
|
||||
/* ------ The following fields are for debugging/tracebacks only ------ */
|
||||
GCRef chunkname; /* Name of the chunk this function was defined in. */
|
||||
BCLine firstline; /* First line of the function definition. */
|
||||
BCLine numline; /* Number of lines for the function definition. */
|
||||
MRef lineinfo; /* Compressed map from bytecode ins. to source line. */
|
||||
MRef uvinfo; /* Upvalue names. */
|
||||
MRef varinfo; /* Names and compressed extents of local variables. */
|
||||
} GCproto;
|
||||
|
||||
/* Flags for prototype. */
|
||||
#define PROTO_CHILD 0x01 /* Has child prototypes. */
|
||||
#define PROTO_VARARG 0x02 /* Vararg function. */
|
||||
#define PROTO_FFI 0x04 /* Uses BC_KCDATA for FFI datatypes. */
|
||||
#define PROTO_NOJIT 0x08 /* JIT disabled for this function. */
|
||||
#define PROTO_ILOOP 0x10 /* Patched bytecode with ILOOP etc. */
|
||||
/* Only used during parsing. */
|
||||
#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */
|
||||
#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */
|
||||
/* Top bits used for counting created closures. */
|
||||
#define PROTO_CLCOUNT 0x20 /* Base of saturating 3 bit counter. */
|
||||
#define PROTO_CLC_BITS 3
|
||||
#define PROTO_CLC_POLY (3*PROTO_CLCOUNT) /* Polymorphic threshold. */
|
||||
|
||||
#define PROTO_UV_LOCAL 0x8000 /* Upvalue for local slot. */
|
||||
#define PROTO_UV_IMMUTABLE 0x4000 /* Immutable upvalue. */
|
||||
|
||||
#define proto_kgc(pt, idx) \
|
||||
check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \
|
||||
gcref(mref((pt)->k, GCRef)[(idx)]))
|
||||
#define proto_knumtv(pt, idx) \
|
||||
check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)])
|
||||
#define proto_bc(pt) ((BCIns *)((char *)(pt) + sizeof(GCproto)))
|
||||
#define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt)))
|
||||
#define proto_uv(pt) (mref((pt)->uv, uint16_t))
|
||||
|
||||
#define proto_chunkname(pt) (strref((pt)->chunkname))
|
||||
#define proto_chunknamestr(pt) (strdata(proto_chunkname((pt))))
|
||||
#define proto_lineinfo(pt) (mref((pt)->lineinfo, const void))
|
||||
#define proto_uvinfo(pt) (mref((pt)->uvinfo, const uint8_t))
|
||||
#define proto_varinfo(pt) (mref((pt)->varinfo, const uint8_t))
|
||||
|
||||
/* -- Upvalue object ------------------------------------------------------ */
|
||||
|
||||
typedef struct GCupval {
|
||||
GCHeader;
|
||||
uint8_t closed; /* Set if closed (i.e. uv->v == &uv->u.value). */
|
||||
uint8_t immutable; /* Immutable value. */
|
||||
union {
|
||||
TValue tv; /* If closed: the value itself. */
|
||||
struct { /* If open: double linked list, anchored at thread. */
|
||||
GCRef prev;
|
||||
GCRef next;
|
||||
};
|
||||
};
|
||||
MRef v; /* Points to stack slot (open) or above (closed). */
|
||||
uint32_t dhash; /* Disambiguation hash: dh1 != dh2 => cannot alias. */
|
||||
} GCupval;
|
||||
|
||||
#define uvprev(uv_) (&gcref((uv_)->prev)->uv)
|
||||
#define uvnext(uv_) (&gcref((uv_)->next)->uv)
|
||||
#define uvval(uv_) (mref((uv_)->v, TValue))
|
||||
|
||||
/* -- Function object (closures) ------------------------------------------ */
|
||||
|
||||
/* Common header for functions. env should be at same offset in GCudata. */
|
||||
#define GCfuncHeader \
|
||||
GCHeader; uint8_t ffid; uint8_t nupvalues; \
|
||||
GCRef env; GCRef gclist; MRef pc
|
||||
|
||||
typedef struct GCfuncC {
|
||||
GCfuncHeader;
|
||||
lua_CFunction f; /* C function to be called. */
|
||||
TValue upvalue[1]; /* Array of upvalues (TValue). */
|
||||
} GCfuncC;
|
||||
|
||||
typedef struct GCfuncL {
|
||||
GCfuncHeader;
|
||||
GCRef uvptr[1]; /* Array of _pointers_ to upvalue objects (GCupval). */
|
||||
} GCfuncL;
|
||||
|
||||
typedef union GCfunc {
|
||||
GCfuncC c;
|
||||
GCfuncL l;
|
||||
} GCfunc;
|
||||
|
||||
#define FF_LUA 0
|
||||
#define FF_C 1
|
||||
#define isluafunc(fn) ((fn)->c.ffid == FF_LUA)
|
||||
#define iscfunc(fn) ((fn)->c.ffid == FF_C)
|
||||
#define isffunc(fn) ((fn)->c.ffid > FF_C)
|
||||
#define funcproto(fn) \
|
||||
check_exp(isluafunc(fn), (GCproto *)(mref((fn)->l.pc, char)-sizeof(GCproto)))
|
||||
#define sizeCfunc(n) (sizeof(GCfuncC)-sizeof(TValue)+sizeof(TValue)*(n))
|
||||
#define sizeLfunc(n) (sizeof(GCfuncL)-sizeof(GCRef)+sizeof(GCRef)*(n))
|
||||
|
||||
/* -- Table object -------------------------------------------------------- */
|
||||
|
||||
/* Hash node. */
|
||||
typedef struct Node {
|
||||
TValue val; /* Value object. Must be first field. */
|
||||
TValue key; /* Key object. */
|
||||
MRef next; /* Hash chain. */
|
||||
#if !LJ_GC64
|
||||
MRef freetop; /* Top of free elements (stored in t->node[0]). */
|
||||
#endif
|
||||
} Node;
|
||||
|
||||
LJ_STATIC_ASSERT(offsetof(Node, val) == 0);
|
||||
|
||||
typedef struct GCtab {
|
||||
GCHeader;
|
||||
uint8_t nomm; /* Negative cache for fast metamethods. */
|
||||
int8_t colo; /* Array colocation. */
|
||||
MRef array; /* Array part. */
|
||||
GCRef gclist;
|
||||
GCRef metatable; /* Must be at same offset in GCudata. */
|
||||
MRef node; /* Hash part. */
|
||||
uint32_t asize; /* Size of array part (keys [0, asize-1]). */
|
||||
uint32_t hmask; /* Hash part mask (size of hash part - 1). */
|
||||
#if LJ_GC64
|
||||
MRef freetop; /* Top of free elements. */
|
||||
#endif
|
||||
} GCtab;
|
||||
|
||||
#define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab))
|
||||
#define tabref(r) (&gcref((r))->tab)
|
||||
#define noderef(r) (mref((r), Node))
|
||||
#define nextnode(n) (mref((n)->next, Node))
|
||||
#if LJ_GC64
|
||||
#define getfreetop(t, n) (noderef((t)->freetop))
|
||||
#define setfreetop(t, n, v) (setmref((t)->freetop, (v)))
|
||||
#else
|
||||
#define getfreetop(t, n) (noderef((n)->freetop))
|
||||
#define setfreetop(t, n, v) (setmref((n)->freetop, (v)))
|
||||
#endif
|
||||
|
||||
/* -- State objects ------------------------------------------------------- */
|
||||
|
||||
/* VM states. */
|
||||
enum {
|
||||
LJ_VMST_INTERP, /* Interpreter. */
|
||||
LJ_VMST_C, /* C function. */
|
||||
LJ_VMST_GC, /* Garbage collector. */
|
||||
LJ_VMST_EXIT, /* Trace exit handler. */
|
||||
LJ_VMST_RECORD, /* Trace recorder. */
|
||||
LJ_VMST_OPT, /* Optimizer. */
|
||||
LJ_VMST_ASM, /* Assembler. */
|
||||
LJ_VMST__MAX
|
||||
};
|
||||
|
||||
#define setvmstate(g, st) ((g)->vmstate = ~LJ_VMST_##st)
|
||||
|
||||
/* Metamethods. ORDER MM */
|
||||
#ifdef LJ_HASFFI
|
||||
#define MMDEF_FFI(_) _(new)
|
||||
#else
|
||||
#define MMDEF_FFI(_)
|
||||
#endif
|
||||
|
||||
#if LJ_52 || LJ_HASFFI
|
||||
#define MMDEF_PAIRS(_) _(pairs) _(ipairs)
|
||||
#else
|
||||
#define MMDEF_PAIRS(_)
|
||||
#define MM_pairs 255
|
||||
#define MM_ipairs 255
|
||||
#endif
|
||||
|
||||
#define MMDEF(_) \
|
||||
_(index) _(newindex) _(gc) _(mode) _(eq) _(len) \
|
||||
/* Only the above (fast) metamethods are negative cached (max. 8). */ \
|
||||
_(lt) _(le) _(concat) _(call) \
|
||||
/* The following must be in ORDER ARITH. */ \
|
||||
_(add) _(sub) _(mul) _(div) _(mod) _(pow) _(unm) \
|
||||
/* The following are used in the standard libraries. */ \
|
||||
_(metatable) _(tostring) MMDEF_FFI(_) MMDEF_PAIRS(_)
|
||||
|
||||
typedef enum {
|
||||
#define MMENUM(name) MM_##name,
|
||||
MMDEF(MMENUM)
|
||||
#undef MMENUM
|
||||
MM__MAX,
|
||||
MM____ = MM__MAX,
|
||||
MM_FAST = MM_len
|
||||
} MMS;
|
||||
|
||||
/* GC root IDs. */
|
||||
typedef enum {
|
||||
GCROOT_MMNAME, /* Metamethod names. */
|
||||
GCROOT_MMNAME_LAST = GCROOT_MMNAME + MM__MAX-1,
|
||||
GCROOT_BASEMT, /* Metatables for base types. */
|
||||
GCROOT_BASEMT_NUM = GCROOT_BASEMT + ~LJ_TNUMX,
|
||||
GCROOT_IO_INPUT, /* Userdata for default I/O input file. */
|
||||
GCROOT_IO_OUTPUT, /* Userdata for default I/O output file. */
|
||||
GCROOT_MAX
|
||||
} GCRootID;
|
||||
|
||||
#define basemt_it(g, it) ((g)->gcroot[GCROOT_BASEMT+~(it)])
|
||||
#define basemt_obj(g, o) ((g)->gcroot[GCROOT_BASEMT+itypemap(o)])
|
||||
#define mmname_str(g, mm) (strref((g)->gcroot[GCROOT_MMNAME+(mm)]))
|
||||
|
||||
typedef struct GCState {
|
||||
GCSize total; /* Memory currently allocated. */
|
||||
GCSize threshold; /* Memory threshold. */
|
||||
uint8_t currentwhite; /* Current white color. */
|
||||
uint8_t state; /* GC state. */
|
||||
uint8_t nocdatafin; /* No cdata finalizer called. */
|
||||
uint8_t unused2;
|
||||
MSize sweepstr; /* Sweep position in string table. */
|
||||
GCRef root; /* List of all collectable objects. */
|
||||
MRef sweep; /* Sweep position in root list. */
|
||||
GCRef gray; /* List of gray objects. */
|
||||
GCRef grayagain; /* List of objects for atomic traversal. */
|
||||
GCRef weak; /* List of weak tables (to be cleared). */
|
||||
GCRef mmudata; /* List of userdata (to be finalized). */
|
||||
GCSize debt; /* Debt (how much GC is behind schedule). */
|
||||
GCSize estimate; /* Estimate of memory actually in use. */
|
||||
MSize stepmul; /* Incremental GC step granularity. */
|
||||
MSize pause; /* Pause between successive GC cycles. */
|
||||
} GCState;
|
||||
|
||||
/* Global state, shared by all threads of a Lua universe. */
|
||||
typedef struct global_State {
|
||||
GCRef *strhash; /* String hash table (hash chain anchors). */
|
||||
MSize strmask; /* String hash mask (size of hash table - 1). */
|
||||
MSize strnum; /* Number of strings in hash table. */
|
||||
lua_Alloc allocf; /* Memory allocator. */
|
||||
void *allocd; /* Memory allocator data. */
|
||||
GCState gc; /* Garbage collector. */
|
||||
volatile int32_t vmstate; /* VM state or current JIT code trace number. */
|
||||
SBuf tmpbuf; /* Temporary string buffer. */
|
||||
GCstr strempty; /* Empty string. */
|
||||
uint8_t stremptyz; /* Zero terminator of empty string. */
|
||||
uint8_t hookmask; /* Hook mask. */
|
||||
uint8_t dispatchmode; /* Dispatch mode. */
|
||||
uint8_t vmevmask; /* VM event mask. */
|
||||
GCRef mainthref; /* Link to main thread. */
|
||||
TValue registrytv; /* Anchor for registry. */
|
||||
TValue tmptv, tmptv2; /* Temporary TValues. */
|
||||
Node nilnode; /* Fallback 1-element hash part (nil key and value). */
|
||||
GCupval uvhead; /* Head of double-linked list of all open upvalues. */
|
||||
int32_t hookcount; /* Instruction hook countdown. */
|
||||
int32_t hookcstart; /* Start count for instruction hook counter. */
|
||||
lua_Hook hookf; /* Hook function. */
|
||||
lua_CFunction wrapf; /* Wrapper for C function calls. */
|
||||
lua_CFunction panic; /* Called as a last resort for errors. */
|
||||
BCIns bc_cfunc_int; /* Bytecode for internal C function calls. */
|
||||
BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */
|
||||
GCRef cur_L; /* Currently executing lua_State. */
|
||||
MRef jit_base; /* Current JIT code L->base or NULL. */
|
||||
MRef ctype_state; /* Pointer to C type state. */
|
||||
GCRef gcroot[GCROOT_MAX]; /* GC roots. */
|
||||
} global_State;
|
||||
|
||||
#define mainthread(g) (&gcref(g->mainthref)->th)
|
||||
#define niltv(L) \
|
||||
check_exp(tvisnil(&G(L)->nilnode.val), &G(L)->nilnode.val)
|
||||
#define niltvg(g) \
|
||||
check_exp(tvisnil(&(g)->nilnode.val), &(g)->nilnode.val)
|
||||
|
||||
/* Hook management. Hook event masks are defined in lua.h. */
|
||||
#define HOOK_EVENTMASK 0x0f
|
||||
#define HOOK_ACTIVE 0x10
|
||||
#define HOOK_ACTIVE_SHIFT 4
|
||||
#define HOOK_VMEVENT 0x20
|
||||
#define HOOK_GC 0x40
|
||||
#define HOOK_PROFILE 0x80
|
||||
#define hook_active(g) ((g)->hookmask & HOOK_ACTIVE)
|
||||
#define hook_enter(g) ((g)->hookmask |= HOOK_ACTIVE)
|
||||
#define hook_entergc(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_GC))
|
||||
#define hook_vmevent(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_VMEVENT))
|
||||
#define hook_leave(g) ((g)->hookmask &= ~HOOK_ACTIVE)
|
||||
#define hook_save(g) ((g)->hookmask & ~HOOK_EVENTMASK)
|
||||
#define hook_restore(g, h) \
|
||||
((g)->hookmask = ((g)->hookmask & HOOK_EVENTMASK) | (h))
|
||||
|
||||
/* Per-thread state object. */
|
||||
struct lua_State {
|
||||
GCHeader;
|
||||
uint8_t dummy_ffid; /* Fake FF_C for curr_funcisL() on dummy frames. */
|
||||
uint8_t status; /* Thread status. */
|
||||
MRef glref; /* Link to global state. */
|
||||
GCRef gclist; /* GC chain. */
|
||||
TValue *base; /* Base of currently executing function. */
|
||||
TValue *top; /* First free slot in the stack. */
|
||||
MRef maxstack; /* Last free slot in the stack. */
|
||||
MRef stack; /* Stack base. */
|
||||
GCRef openupval; /* List of open upvalues in the stack. */
|
||||
GCRef env; /* Thread environment (table of globals). */
|
||||
void *cframe; /* End of C stack frame chain. */
|
||||
MSize stacksize; /* True stack size (incl. LJ_STACK_EXTRA). */
|
||||
};
|
||||
|
||||
#define G(L) (mref(L->glref, global_State))
|
||||
#define registry(L) (&G(L)->registrytv)
|
||||
|
||||
/* Macros to access the currently executing (Lua) function. */
|
||||
#if LJ_GC64
|
||||
#define curr_func(L) (&gcval(L->base-2)->fn)
|
||||
#elif LJ_FR2
|
||||
#define curr_func(L) (&gcref((L->base-2)->gcr)->fn)
|
||||
#else
|
||||
#define curr_func(L) (&gcref((L->base-1)->fr.func)->fn)
|
||||
#endif
|
||||
#define curr_funcisL(L) (isluafunc(curr_func(L)))
|
||||
#define curr_proto(L) (funcproto(curr_func(L)))
|
||||
#define curr_topL(L) (L->base + curr_proto(L)->framesize)
|
||||
#define curr_top(L) (curr_funcisL(L) ? curr_topL(L) : L->top)
|
||||
|
||||
/* -- GC object definition and conversions -------------------------------- */
|
||||
|
||||
/* GC header for generic access to common fields of GC objects. */
|
||||
typedef struct GChead {
|
||||
GCHeader;
|
||||
uint8_t unused1;
|
||||
uint8_t unused2;
|
||||
GCRef env;
|
||||
GCRef gclist;
|
||||
GCRef metatable;
|
||||
} GChead;
|
||||
|
||||
/* The env field SHOULD be at the same offset for all GC objects. */
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, env) == offsetof(GCfuncL, env));
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, env) == offsetof(GCudata, env));
|
||||
|
||||
/* The metatable field MUST be at the same offset for all GC objects. */
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, metatable) == offsetof(GCtab, metatable));
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, metatable) == offsetof(GCudata, metatable));
|
||||
|
||||
/* The gclist field MUST be at the same offset for all GC objects. */
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(lua_State, gclist));
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCproto, gclist));
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCfuncL, gclist));
|
||||
LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCtab, gclist));
|
||||
|
||||
typedef union GCobj {
|
||||
GChead gch;
|
||||
GCstr str;
|
||||
GCupval uv;
|
||||
lua_State th;
|
||||
GCproto pt;
|
||||
GCfunc fn;
|
||||
GCcdata cd;
|
||||
GCtab tab;
|
||||
GCudata ud;
|
||||
} GCobj;
|
||||
|
||||
/* Macros to convert a GCobj pointer into a specific value. */
|
||||
#define gco2str(o) check_exp((o)->gch.gct == ~LJ_TSTR, &(o)->str)
|
||||
#define gco2uv(o) check_exp((o)->gch.gct == ~LJ_TUPVAL, &(o)->uv)
|
||||
#define gco2th(o) check_exp((o)->gch.gct == ~LJ_TTHREAD, &(o)->th)
|
||||
#define gco2pt(o) check_exp((o)->gch.gct == ~LJ_TPROTO, &(o)->pt)
|
||||
#define gco2func(o) check_exp((o)->gch.gct == ~LJ_TFUNC, &(o)->fn)
|
||||
#define gco2cd(o) check_exp((o)->gch.gct == ~LJ_TCDATA, &(o)->cd)
|
||||
#define gco2tab(o) check_exp((o)->gch.gct == ~LJ_TTAB, &(o)->tab)
|
||||
#define gco2ud(o) check_exp((o)->gch.gct == ~LJ_TUDATA, &(o)->ud)
|
||||
|
||||
/* Macro to convert any collectable object into a GCobj pointer. */
|
||||
#define obj2gco(v) ((GCobj *)(v))
|
||||
|
||||
/* -- TValue getters/setters ---------------------------------------------- */
|
||||
|
||||
#ifdef LUA_USE_ASSERT
|
||||
#include "lj_gc.h"
|
||||
#endif
|
||||
|
||||
/* Macros to test types. */
|
||||
#if LJ_GC64
|
||||
#define itype(o) ((uint32_t)((o)->it64 >> 47))
|
||||
#define tvisnil(o) ((o)->it64 == -1)
|
||||
#else
|
||||
#define itype(o) ((o)->it)
|
||||
#define tvisnil(o) (itype(o) == LJ_TNIL)
|
||||
#endif
|
||||
#define tvisfalse(o) (itype(o) == LJ_TFALSE)
|
||||
#define tvistrue(o) (itype(o) == LJ_TTRUE)
|
||||
#define tvisbool(o) (tvisfalse(o) || tvistrue(o))
|
||||
#if LJ_64 && !LJ_GC64
|
||||
#define tvislightud(o) (((int32_t)itype(o) >> 15) == -2)
|
||||
#else
|
||||
#define tvislightud(o) (itype(o) == LJ_TLIGHTUD)
|
||||
#endif
|
||||
#define tvisstr(o) (itype(o) == LJ_TSTR)
|
||||
#define tvisfunc(o) (itype(o) == LJ_TFUNC)
|
||||
#define tvisthread(o) (itype(o) == LJ_TTHREAD)
|
||||
#define tvisproto(o) (itype(o) == LJ_TPROTO)
|
||||
#define tviscdata(o) (itype(o) == LJ_TCDATA)
|
||||
#define tvistab(o) (itype(o) == LJ_TTAB)
|
||||
#define tvisudata(o) (itype(o) == LJ_TUDATA)
|
||||
#define tvisnumber(o) (itype(o) <= LJ_TISNUM)
|
||||
#define tvisint(o) (LJ_DUALNUM && itype(o) == LJ_TISNUM)
|
||||
#define tvisnum(o) (itype(o) < LJ_TISNUM)
|
||||
|
||||
#define tvistruecond(o) (itype(o) < LJ_TISTRUECOND)
|
||||
#define tvispri(o) (itype(o) >= LJ_TISPRI)
|
||||
#define tvistabud(o) (itype(o) <= LJ_TISTABUD) /* && !tvisnum() */
|
||||
#define tvisgcv(o) ((itype(o) - LJ_TISGCV) > (LJ_TNUMX - LJ_TISGCV))
|
||||
|
||||
/* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */
|
||||
#define tvisnan(o) ((o)->n != (o)->n)
|
||||
#if LJ_64
|
||||
#define tviszero(o) (((o)->u64 << 1) == 0)
|
||||
#else
|
||||
#define tviszero(o) (((o)->u32.lo | ((o)->u32.hi << 1)) == 0)
|
||||
#endif
|
||||
#define tvispzero(o) ((o)->u64 == 0)
|
||||
#define tvismzero(o) ((o)->u64 == U64x(80000000,00000000))
|
||||
#define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000))
|
||||
#define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64)
|
||||
|
||||
/* Macros to convert type ids. */
|
||||
#if LJ_64 && !LJ_GC64
|
||||
#define itypemap(o) \
|
||||
(tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o))
|
||||
#else
|
||||
#define itypemap(o) (tvisnumber(o) ? ~LJ_TNUMX : ~itype(o))
|
||||
#endif
|
||||
|
||||
/* Macros to get tagged values. */
|
||||
#if LJ_GC64
|
||||
#define gcval(o) ((GCobj *)(gcrefu((o)->gcr) & LJ_GCVMASK))
|
||||
#else
|
||||
#define gcval(o) (gcref((o)->gcr))
|
||||
#endif
|
||||
#define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - itype(o)))
|
||||
#if LJ_64
|
||||
#define lightudV(o) \
|
||||
check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff)))
|
||||
#else
|
||||
#define lightudV(o) check_exp(tvislightud(o), gcrefp((o)->gcr, void))
|
||||
#endif
|
||||
#define gcV(o) check_exp(tvisgcv(o), gcval(o))
|
||||
#define strV(o) check_exp(tvisstr(o), &gcval(o)->str)
|
||||
#define funcV(o) check_exp(tvisfunc(o), &gcval(o)->fn)
|
||||
#define threadV(o) check_exp(tvisthread(o), &gcval(o)->th)
|
||||
#define protoV(o) check_exp(tvisproto(o), &gcval(o)->pt)
|
||||
#define cdataV(o) check_exp(tviscdata(o), &gcval(o)->cd)
|
||||
#define tabV(o) check_exp(tvistab(o), &gcval(o)->tab)
|
||||
#define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud)
|
||||
#define numV(o) check_exp(tvisnum(o), (o)->n)
|
||||
#define intV(o) check_exp(tvisint(o), (int32_t)(o)->i)
|
||||
|
||||
/* Macros to set tagged values. */
|
||||
#if LJ_GC64
|
||||
#define setitype(o, i) ((o)->it = ((i) << 15))
|
||||
#define setnilV(o) ((o)->it64 = -1)
|
||||
#define setpriV(o, x) ((o)->it64 = (int64_t)~((uint64_t)~(x)<<47))
|
||||
#define setboolV(o, x) ((o)->it64 = (int64_t)~((uint64_t)((x)+1)<<47))
|
||||
#else
|
||||
#define setitype(o, i) ((o)->it = (i))
|
||||
#define setnilV(o) ((o)->it = LJ_TNIL)
|
||||
#define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x))
|
||||
#define setpriV(o, i) (setitype((o), (i)))
|
||||
#endif
|
||||
|
||||
static LJ_AINLINE void setlightudV(TValue *o, void *p)
|
||||
{
|
||||
#if LJ_GC64
|
||||
o->u64 = (uint64_t)p | (((uint64_t)LJ_TLIGHTUD) << 47);
|
||||
#elif LJ_64
|
||||
o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48);
|
||||
#else
|
||||
setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
#define checklightudptr(L, p) \
|
||||
(((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p))
|
||||
#else
|
||||
#define checklightudptr(L, p) (p)
|
||||
#endif
|
||||
|
||||
#if LJ_FR2
|
||||
#define contptr(f) ((void *)(f))
|
||||
#define setcont(o, f) ((o)->u64 = (uint64_t)(uintptr_t)contptr(f))
|
||||
#elif LJ_64
|
||||
#define contptr(f) \
|
||||
((void *)(uintptr_t)(uint32_t)((intptr_t)(f) - (intptr_t)lj_vm_asm_begin))
|
||||
#define setcont(o, f) \
|
||||
((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin)
|
||||
#else
|
||||
#define contptr(f) ((void *)(f))
|
||||
#define setcont(o, f) setlightudV((o), contptr(f))
|
||||
#endif
|
||||
|
||||
#define tvchecklive(L, o) \
|
||||
UNUSED(L), lua_assert(!tvisgcv(o) || \
|
||||
((~itype(o) == gcval(o)->gch.gct) && !isdead(G(L), gcval(o))))
|
||||
|
||||
static LJ_AINLINE void setgcVraw(TValue *o, GCobj *v, uint32_t itype)
|
||||
{
|
||||
#if LJ_GC64
|
||||
setgcreft(o->gcr, v, itype);
|
||||
#else
|
||||
setgcref(o->gcr, v); setitype(o, itype);
|
||||
#endif
|
||||
}
|
||||
|
||||
static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t it)
|
||||
{
|
||||
setgcVraw(o, v, it); tvchecklive(L, o);
|
||||
}
|
||||
|
||||
#define define_setV(name, type, tag) \
|
||||
static LJ_AINLINE void name(lua_State *L, TValue *o, type *v) \
|
||||
{ \
|
||||
setgcV(L, o, obj2gco(v), tag); \
|
||||
}
|
||||
define_setV(setstrV, GCstr, LJ_TSTR)
|
||||
define_setV(setthreadV, lua_State, LJ_TTHREAD)
|
||||
define_setV(setprotoV, GCproto, LJ_TPROTO)
|
||||
define_setV(setfuncV, GCfunc, LJ_TFUNC)
|
||||
define_setV(setcdataV, GCcdata, LJ_TCDATA)
|
||||
define_setV(settabV, GCtab, LJ_TTAB)
|
||||
define_setV(setudataV, GCudata, LJ_TUDATA)
|
||||
|
||||
#define setnumV(o, x) ((o)->n = (x))
|
||||
#define setnanV(o) ((o)->u64 = U64x(fff80000,00000000))
|
||||
#define setpinfV(o) ((o)->u64 = U64x(7ff00000,00000000))
|
||||
#define setminfV(o) ((o)->u64 = U64x(fff00000,00000000))
|
||||
|
||||
static LJ_AINLINE void setintV(TValue *o, int32_t i)
|
||||
{
|
||||
#if LJ_DUALNUM
|
||||
o->i = (uint32_t)i; setitype(o, LJ_TISNUM);
|
||||
#else
|
||||
o->n = (lua_Number)i;
|
||||
#endif
|
||||
}
|
||||
|
||||
static LJ_AINLINE void setint64V(TValue *o, int64_t i)
|
||||
{
|
||||
if (LJ_DUALNUM && LJ_LIKELY(i == (int64_t)(int32_t)i))
|
||||
setintV(o, (int32_t)i);
|
||||
else
|
||||
setnumV(o, (lua_Number)i);
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
#define setintptrV(o, i) setint64V((o), (i))
|
||||
#else
|
||||
#define setintptrV(o, i) setintV((o), (i))
|
||||
#endif
|
||||
|
||||
/* Copy tagged values. */
|
||||
static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2)
|
||||
{
|
||||
*o1 = *o2; tvchecklive(L, o1);
|
||||
}
|
||||
|
||||
/* -- Number to integer conversion ---------------------------------------- */
|
||||
|
||||
#if LJ_SOFTFP
|
||||
LJ_ASMF int32_t lj_vm_tobit(double x);
|
||||
#endif
|
||||
|
||||
static LJ_AINLINE int32_t lj_num2bit(lua_Number n)
|
||||
{
|
||||
#if LJ_SOFTFP
|
||||
return lj_vm_tobit(n);
|
||||
#else
|
||||
TValue o;
|
||||
o.n = n + 6755399441055744.0; /* 2^52 + 2^51 */
|
||||
return (int32_t)o.u32.lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define lj_num2int(n) ((int32_t)(n))
|
||||
|
||||
static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
if (n >= 9223372036854775808.0) /* They think it's a feature. */
|
||||
return (uint64_t)(int64_t)(n - 18446744073709551616.0);
|
||||
else
|
||||
#endif
|
||||
return (uint64_t)n;
|
||||
}
|
||||
|
||||
static LJ_AINLINE int32_t numberVint(cTValue *o)
|
||||
{
|
||||
if (LJ_LIKELY(tvisint(o)))
|
||||
return intV(o);
|
||||
else
|
||||
return lj_num2int(numV(o));
|
||||
}
|
||||
|
||||
static LJ_AINLINE lua_Number numberVnum(cTValue *o)
|
||||
{
|
||||
if (LJ_UNLIKELY(tvisint(o)))
|
||||
return (lua_Number)intV(o);
|
||||
else
|
||||
return numV(o);
|
||||
}
|
||||
|
||||
/* -- Miscellaneous object handling --------------------------------------- */
|
||||
|
||||
/* Names and maps for internal and external object tags. */
|
||||
LJ_DATA const char *const lj_obj_typename[1+LUA_TCDATA+1];
|
||||
LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1];
|
||||
|
||||
#define lj_typename(o) (lj_obj_itypename[itypemap(o)])
|
||||
|
||||
/* Compare two objects without calling metamethods. */
|
||||
LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2);
|
||||
LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(cTValue *o);
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
** Lua parser (source code -> bytecode).
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_PARSE_H
|
||||
#define _LJ_PARSE_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_lex.h"
|
||||
|
||||
LJ_FUNC GCproto *lj_parse(LexState *ls);
|
||||
LJ_FUNC GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t l);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
** Low-overhead profiling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_PROFILE_H
|
||||
#define _LJ_PROFILE_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
#if LJ_HASPROFILE
|
||||
|
||||
LJ_FUNC void LJ_FASTCALL lj_profile_interpreter(lua_State *L);
|
||||
#if !LJ_PROFILE_SIGPROF
|
||||
LJ_FUNC void LJ_FASTCALL lj_profile_hook_enter(global_State *g);
|
||||
LJ_FUNC void LJ_FASTCALL lj_profile_hook_leave(global_State *g);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,271 +0,0 @@
|
||||
/* This is a generated file. DO NOT EDIT! */
|
||||
|
||||
static const uint16_t recff_idmap[] = {
|
||||
0,
|
||||
0x0100,
|
||||
0x0200,
|
||||
0x0300,
|
||||
0,
|
||||
0x0400+(0),
|
||||
0x0500,
|
||||
0x0400+(1),
|
||||
0x0600,
|
||||
0x0700,
|
||||
0x0800,
|
||||
0,
|
||||
0x0900,
|
||||
0x0a00,
|
||||
0x0b00,
|
||||
0,
|
||||
0x0c00,
|
||||
0x0d00,
|
||||
0x0e00,
|
||||
0,
|
||||
0x0f00,
|
||||
0x1000,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x1100,
|
||||
0x1200+(IRFPM_FLOOR),
|
||||
0x1200+(IRFPM_CEIL),
|
||||
0x1300+(IRFPM_SQRT),
|
||||
0x1300+(IRFPM_LOG10),
|
||||
0x1300+(IRFPM_EXP),
|
||||
0x1300+(IRFPM_SIN),
|
||||
0x1300+(IRFPM_COS),
|
||||
0x1300+(IRFPM_TAN),
|
||||
0x1400+(FF_math_asin),
|
||||
0x1400+(FF_math_acos),
|
||||
0x1400+(FF_math_atan),
|
||||
0x1500+(IRCALL_sinh),
|
||||
0x1500+(IRCALL_cosh),
|
||||
0x1500+(IRCALL_tanh),
|
||||
0,
|
||||
0x1600,
|
||||
0x1700,
|
||||
0x1800,
|
||||
0x1900,
|
||||
0,
|
||||
0x1a00,
|
||||
0x1b00+(IR_MIN),
|
||||
0x1b00+(IR_MAX),
|
||||
0x1c00,
|
||||
0,
|
||||
0x1d00,
|
||||
0x1e00+(IR_BNOT),
|
||||
0x1e00+(IR_BSWAP),
|
||||
0x1f00+(IR_BSHL),
|
||||
0x1f00+(IR_BSHR),
|
||||
0x1f00+(IR_BSAR),
|
||||
0x1f00+(IR_BROL),
|
||||
0x1f00+(IR_BROR),
|
||||
0x2000+(IR_BAND),
|
||||
0x2000+(IR_BOR),
|
||||
0x2000+(IR_BXOR),
|
||||
0x2100,
|
||||
0x2200+(0),
|
||||
0x2300,
|
||||
0x2200+(1),
|
||||
0x2400,
|
||||
0x2500+(IRCALL_lj_buf_putstr_reverse),
|
||||
0x2500+(IRCALL_lj_buf_putstr_lower),
|
||||
0x2500+(IRCALL_lj_buf_putstr_upper),
|
||||
0,
|
||||
0x2600,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x2700,
|
||||
0,
|
||||
0x2800,
|
||||
0x2900,
|
||||
0,
|
||||
0x2a00,
|
||||
0x2b00,
|
||||
0,
|
||||
0,
|
||||
0x2c00+(0),
|
||||
0x2d00+(0),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x2c00+(GCROOT_IO_OUTPUT),
|
||||
0x2d00+(GCROOT_IO_OUTPUT),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x2e00,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x2f00+(0),
|
||||
0x2f00+(1),
|
||||
0x3000+(MM_eq),
|
||||
0x3000+(MM_len),
|
||||
0x3000+(MM_lt),
|
||||
0x3000+(MM_le),
|
||||
0x3000+(MM_concat),
|
||||
0x3100,
|
||||
0x3000+(MM_add),
|
||||
0x3000+(MM_sub),
|
||||
0x3000+(MM_mul),
|
||||
0x3000+(MM_div),
|
||||
0x3000+(MM_mod),
|
||||
0x3000+(MM_pow),
|
||||
0x3000+(MM_unm),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x3200+(1),
|
||||
0x3200+(0),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x3300,
|
||||
0x3300,
|
||||
0x3400,
|
||||
0,
|
||||
0x3500,
|
||||
0x3600+(FF_ffi_sizeof),
|
||||
0x3600+(FF_ffi_alignof),
|
||||
0x3600+(FF_ffi_offsetof),
|
||||
0x3700,
|
||||
0x3800,
|
||||
0x3900,
|
||||
0x3a00,
|
||||
0x3b00,
|
||||
0,
|
||||
0x3c00
|
||||
};
|
||||
|
||||
static const RecordFunc recff_func[] = {
|
||||
recff_nyi,
|
||||
recff_c,
|
||||
recff_assert,
|
||||
recff_type,
|
||||
recff_xpairs,
|
||||
recff_ipairs_aux,
|
||||
recff_getmetatable,
|
||||
recff_setmetatable,
|
||||
recff_getfenv,
|
||||
recff_rawget,
|
||||
recff_rawset,
|
||||
recff_rawequal,
|
||||
recff_select,
|
||||
recff_tonumber,
|
||||
recff_tostring,
|
||||
recff_pcall,
|
||||
recff_xpcall,
|
||||
recff_math_abs,
|
||||
recff_math_round,
|
||||
recff_math_unary,
|
||||
recff_math_atrig,
|
||||
recff_math_htrig,
|
||||
recff_math_modf,
|
||||
recff_math_log,
|
||||
recff_math_atan2,
|
||||
recff_math_pow,
|
||||
recff_math_ldexp,
|
||||
recff_math_minmax,
|
||||
recff_math_random,
|
||||
recff_bit_tobit,
|
||||
recff_bit_unary,
|
||||
recff_bit_shift,
|
||||
recff_bit_nary,
|
||||
recff_bit_tohex,
|
||||
recff_string_range,
|
||||
recff_string_char,
|
||||
recff_string_rep,
|
||||
recff_string_op,
|
||||
recff_string_find,
|
||||
recff_string_format,
|
||||
recff_table_insert,
|
||||
recff_table_concat,
|
||||
recff_table_new,
|
||||
recff_table_clear,
|
||||
recff_io_write,
|
||||
recff_io_flush,
|
||||
recff_debug_getmetatable,
|
||||
recff_cdata_index,
|
||||
recff_cdata_arith,
|
||||
recff_cdata_call,
|
||||
recff_clib_index,
|
||||
recff_ffi_new,
|
||||
recff_ffi_typeof,
|
||||
recff_ffi_istype,
|
||||
recff_ffi_xof,
|
||||
recff_ffi_errno,
|
||||
recff_ffi_string,
|
||||
recff_ffi_copy,
|
||||
recff_ffi_fill,
|
||||
recff_ffi_abi,
|
||||
recff_ffi_gc
|
||||
};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
** Trace recorder (bytecode -> SSA IR).
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_RECORD_H
|
||||
#define _LJ_RECORD_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_jit.h"
|
||||
|
||||
#if LJ_HASJIT
|
||||
/* Context for recording an indexed load/store. */
|
||||
typedef struct RecordIndex {
|
||||
TValue tabv; /* Runtime value of table (or indexed object). */
|
||||
TValue keyv; /* Runtime value of key. */
|
||||
TValue valv; /* Runtime value of stored value. */
|
||||
TValue mobjv; /* Runtime value of metamethod object. */
|
||||
GCtab *mtv; /* Runtime value of metatable object. */
|
||||
cTValue *oldv; /* Runtime value of previously stored value. */
|
||||
TRef tab; /* Table (or indexed object) reference. */
|
||||
TRef key; /* Key reference. */
|
||||
TRef val; /* Value reference for a store or 0 for a load. */
|
||||
TRef mt; /* Metatable reference. */
|
||||
TRef mobj; /* Metamethod object reference. */
|
||||
int idxchain; /* Index indirections left or 0 for raw lookup. */
|
||||
} RecordIndex;
|
||||
|
||||
LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
|
||||
cTValue *av, cTValue *bv);
|
||||
LJ_FUNC void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk);
|
||||
LJ_FUNC TRef lj_record_constify(jit_State *J, cTValue *o);
|
||||
|
||||
LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs);
|
||||
LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs);
|
||||
LJ_FUNC void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults);
|
||||
|
||||
LJ_FUNC int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm);
|
||||
LJ_FUNC TRef lj_record_idx(jit_State *J, RecordIndex *ix);
|
||||
|
||||
LJ_FUNC void lj_record_ins(jit_State *J);
|
||||
LJ_FUNC void lj_record_setup(jit_State *J);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
** Snapshot handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_SNAP_H
|
||||
#define _LJ_SNAP_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_jit.h"
|
||||
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC void lj_snap_add(jit_State *J);
|
||||
LJ_FUNC void lj_snap_purge(jit_State *J);
|
||||
LJ_FUNC void lj_snap_shrink(jit_State *J);
|
||||
LJ_FUNC IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir);
|
||||
LJ_FUNC void lj_snap_replay(jit_State *J, GCtrace *T);
|
||||
LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr);
|
||||
LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need);
|
||||
LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need);
|
||||
|
||||
static LJ_AINLINE void lj_snap_grow_buf(jit_State *J, MSize need)
|
||||
{
|
||||
if (LJ_UNLIKELY(need > J->sizesnap)) lj_snap_grow_buf_(J, need);
|
||||
}
|
||||
|
||||
static LJ_AINLINE void lj_snap_grow_map(jit_State *J, MSize need)
|
||||
{
|
||||
if (LJ_UNLIKELY(need > J->sizesnapmap)) lj_snap_grow_map_(J, need);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
** State and stack handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_STATE_H
|
||||
#define _LJ_STATE_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
#define incr_top(L) \
|
||||
(++L->top >= tvref(L->maxstack) && (lj_state_growstack1(L), 0))
|
||||
|
||||
#define savestack(L, p) ((char *)(p) - mref(L->stack, char))
|
||||
#define restorestack(L, n) ((TValue *)(mref(L->stack, char) + (n)))
|
||||
|
||||
LJ_FUNC void lj_state_relimitstack(lua_State *L);
|
||||
LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used);
|
||||
LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need);
|
||||
LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L);
|
||||
|
||||
static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need)
|
||||
{
|
||||
if ((mref(L->maxstack, char) - (char *)L->top) <=
|
||||
(ptrdiff_t)need*(ptrdiff_t)sizeof(TValue))
|
||||
lj_state_growstack(L, need);
|
||||
}
|
||||
|
||||
LJ_FUNC lua_State *lj_state_new(lua_State *L);
|
||||
LJ_FUNC void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L);
|
||||
#if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC))
|
||||
LJ_FUNC lua_State *lj_state_newstate(lua_Alloc f, void *ud);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
** String handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_STR_H
|
||||
#define _LJ_STR_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* String helpers. */
|
||||
LJ_FUNC int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b);
|
||||
LJ_FUNC const char *lj_str_find(const char *s, const char *f,
|
||||
MSize slen, MSize flen);
|
||||
LJ_FUNC int lj_str_haspattern(GCstr *s);
|
||||
|
||||
/* String interning. */
|
||||
LJ_FUNC void lj_str_resize(lua_State *L, MSize newmask);
|
||||
LJ_FUNCA GCstr *lj_str_new(lua_State *L, const char *str, size_t len);
|
||||
LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
|
||||
|
||||
#define lj_str_newz(L, s) (lj_str_new(L, s, strlen(s)))
|
||||
#define lj_str_newlit(L, s) (lj_str_new(L, "" s, sizeof(s)-1))
|
||||
|
||||
#endif
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
** String formatting.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_STRFMT_H
|
||||
#define _LJ_STRFMT_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
typedef uint32_t SFormat; /* Format indicator. */
|
||||
|
||||
/* Format parser state. */
|
||||
typedef struct FormatState {
|
||||
const uint8_t *p; /* Current format string pointer. */
|
||||
const uint8_t *e; /* End of format string. */
|
||||
const char *str; /* Returned literal string. */
|
||||
MSize len; /* Size of literal string. */
|
||||
} FormatState;
|
||||
|
||||
/* Format types (max. 16). */
|
||||
typedef enum FormatType {
|
||||
STRFMT_EOF, STRFMT_ERR, STRFMT_LIT,
|
||||
STRFMT_INT, STRFMT_UINT, STRFMT_NUM, STRFMT_STR, STRFMT_CHAR, STRFMT_PTR
|
||||
} FormatType;
|
||||
|
||||
/* Format subtypes (bits are reused). */
|
||||
#define STRFMT_T_HEX 0x0010 /* STRFMT_UINT */
|
||||
#define STRFMT_T_OCT 0x0020 /* STRFMT_UINT */
|
||||
#define STRFMT_T_FP_A 0x0000 /* STRFMT_NUM */
|
||||
#define STRFMT_T_FP_E 0x0010 /* STRFMT_NUM */
|
||||
#define STRFMT_T_FP_F 0x0020 /* STRFMT_NUM */
|
||||
#define STRFMT_T_FP_G 0x0030 /* STRFMT_NUM */
|
||||
#define STRFMT_T_QUOTED 0x0010 /* STRFMT_STR */
|
||||
|
||||
/* Format flags. */
|
||||
#define STRFMT_F_LEFT 0x0100
|
||||
#define STRFMT_F_PLUS 0x0200
|
||||
#define STRFMT_F_ZERO 0x0400
|
||||
#define STRFMT_F_SPACE 0x0800
|
||||
#define STRFMT_F_ALT 0x1000
|
||||
#define STRFMT_F_UPPER 0x2000
|
||||
|
||||
/* Format indicator fields. */
|
||||
#define STRFMT_SH_WIDTH 16
|
||||
#define STRFMT_SH_PREC 24
|
||||
|
||||
#define STRFMT_TYPE(sf) ((FormatType)((sf) & 15))
|
||||
#define STRFMT_WIDTH(sf) (((sf) >> STRFMT_SH_WIDTH) & 255u)
|
||||
#define STRFMT_PREC(sf) ((((sf) >> STRFMT_SH_PREC) & 255u) - 1u)
|
||||
#define STRFMT_FP(sf) (((sf) >> 4) & 3)
|
||||
|
||||
/* Formats for conversion characters. */
|
||||
#define STRFMT_A (STRFMT_NUM|STRFMT_T_FP_A)
|
||||
#define STRFMT_C (STRFMT_CHAR)
|
||||
#define STRFMT_D (STRFMT_INT)
|
||||
#define STRFMT_E (STRFMT_NUM|STRFMT_T_FP_E)
|
||||
#define STRFMT_F (STRFMT_NUM|STRFMT_T_FP_F)
|
||||
#define STRFMT_G (STRFMT_NUM|STRFMT_T_FP_G)
|
||||
#define STRFMT_I STRFMT_D
|
||||
#define STRFMT_O (STRFMT_UINT|STRFMT_T_OCT)
|
||||
#define STRFMT_P (STRFMT_PTR)
|
||||
#define STRFMT_Q (STRFMT_STR|STRFMT_T_QUOTED)
|
||||
#define STRFMT_S (STRFMT_STR)
|
||||
#define STRFMT_U (STRFMT_UINT)
|
||||
#define STRFMT_X (STRFMT_UINT|STRFMT_T_HEX)
|
||||
#define STRFMT_G14 (STRFMT_G | ((14+1) << STRFMT_SH_PREC))
|
||||
|
||||
/* Maximum buffer sizes for conversions. */
|
||||
#define STRFMT_MAXBUF_XINT (1+22) /* '0' prefix + uint64_t in octal. */
|
||||
#define STRFMT_MAXBUF_INT (1+10) /* Sign + int32_t in decimal. */
|
||||
#define STRFMT_MAXBUF_NUM 32 /* Must correspond with STRFMT_G14. */
|
||||
#define STRFMT_MAXBUF_PTR (2+2*sizeof(ptrdiff_t)) /* "0x" + hex ptr. */
|
||||
|
||||
/* Format parser. */
|
||||
LJ_FUNC SFormat LJ_FASTCALL lj_strfmt_parse(FormatState *fs);
|
||||
|
||||
static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len)
|
||||
{
|
||||
fs->p = (const uint8_t *)p;
|
||||
fs->e = (const uint8_t *)p + len;
|
||||
lua_assert(*fs->e == 0); /* Must be NUL-terminated (may have NULs inside). */
|
||||
}
|
||||
|
||||
/* Raw conversions. */
|
||||
LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k);
|
||||
LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v);
|
||||
LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v);
|
||||
LJ_FUNC const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp);
|
||||
|
||||
/* Unformatted conversions to buffer. */
|
||||
LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o);
|
||||
#endif
|
||||
LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putptr(SBuf *sb, const void *v);
|
||||
LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str);
|
||||
|
||||
/* Formatted conversions to buffer. */
|
||||
LJ_FUNC SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k);
|
||||
LJ_FUNC SBuf *lj_strfmt_putfnum_int(SBuf *sb, SFormat sf, lua_Number n);
|
||||
LJ_FUNC SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n);
|
||||
LJ_FUNC SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat, lua_Number n);
|
||||
LJ_FUNC SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat, int32_t c);
|
||||
LJ_FUNC SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat, GCstr *str);
|
||||
|
||||
/* Conversions to strings. */
|
||||
LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k);
|
||||
LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o);
|
||||
LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_char(lua_State *L, int c);
|
||||
#endif
|
||||
LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_obj(lua_State *L, cTValue *o);
|
||||
|
||||
/* Internal string formatting. */
|
||||
LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt,
|
||||
va_list argp);
|
||||
LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#endif
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
** String scanning.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_STRSCAN_H
|
||||
#define _LJ_STRSCAN_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* Options for accepted/returned formats. */
|
||||
#define STRSCAN_OPT_TOINT 0x01 /* Convert to int32_t, if possible. */
|
||||
#define STRSCAN_OPT_TONUM 0x02 /* Always convert to double. */
|
||||
#define STRSCAN_OPT_IMAG 0x04
|
||||
#define STRSCAN_OPT_LL 0x08
|
||||
#define STRSCAN_OPT_C 0x10
|
||||
|
||||
/* Returned format. */
|
||||
typedef enum {
|
||||
STRSCAN_ERROR,
|
||||
STRSCAN_NUM, STRSCAN_IMAG,
|
||||
STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64,
|
||||
} StrScanFmt;
|
||||
|
||||
LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, TValue *o, uint32_t opt);
|
||||
LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o);
|
||||
#if LJ_DUALNUM
|
||||
LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);
|
||||
#else
|
||||
#define lj_strscan_number(s, o) lj_strscan_num((s), (o))
|
||||
#endif
|
||||
|
||||
/* Check for number or convert string to number/int in-place (!). */
|
||||
static LJ_AINLINE int lj_strscan_numberobj(TValue *o)
|
||||
{
|
||||
return tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), o));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
** Table handling.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_TAB_H
|
||||
#define _LJ_TAB_H
|
||||
|
||||
#include "lj_obj.h"
|
||||
|
||||
/* Hash constants. Tuned using a brute force search. */
|
||||
#define HASH_BIAS (-0x04c11db7)
|
||||
#define HASH_ROT1 14
|
||||
#define HASH_ROT2 5
|
||||
#define HASH_ROT3 13
|
||||
|
||||
/* Scramble the bits of numbers and pointers. */
|
||||
static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi)
|
||||
{
|
||||
#if LJ_TARGET_X86ORX64
|
||||
/* Prefer variant that compiles well for a 2-operand CPU. */
|
||||
lo ^= hi; hi = lj_rol(hi, HASH_ROT1);
|
||||
lo -= hi; hi = lj_rol(hi, HASH_ROT2);
|
||||
hi ^= lo; hi -= lj_rol(lo, HASH_ROT3);
|
||||
#else
|
||||
lo ^= hi;
|
||||
lo = lo - lj_rol(hi, HASH_ROT1);
|
||||
hi = lo ^ lj_rol(hi, HASH_ROT1 + HASH_ROT2);
|
||||
hi = hi - lj_rol(lo, HASH_ROT3);
|
||||
#endif
|
||||
return hi;
|
||||
}
|
||||
|
||||
#define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0)
|
||||
|
||||
LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits);
|
||||
LJ_FUNC GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
|
||||
#endif
|
||||
LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
|
||||
LJ_FUNC void LJ_FASTCALL lj_tab_clear(GCtab *t);
|
||||
LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
|
||||
#endif
|
||||
LJ_FUNC void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits);
|
||||
LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);
|
||||
|
||||
/* Caveat: all getters except lj_tab_get() can return NULL! */
|
||||
|
||||
LJ_FUNCA cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key);
|
||||
LJ_FUNC cTValue *lj_tab_getstr(GCtab *t, GCstr *key);
|
||||
LJ_FUNCA cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key);
|
||||
|
||||
/* Caveat: all setters require a write barrier for the stored value. */
|
||||
|
||||
LJ_FUNCA TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key);
|
||||
LJ_FUNCA TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key);
|
||||
LJ_FUNC TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key);
|
||||
LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key);
|
||||
|
||||
#define inarray(t, key) ((MSize)(key) < (MSize)(t)->asize)
|
||||
#define arrayslot(t, i) (&tvref((t)->array)[(i)])
|
||||
#define lj_tab_getint(t, key) \
|
||||
(inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_getinth((t), (key)))
|
||||
#define lj_tab_setint(L, t, key) \
|
||||
(inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_setinth(L, (t), (key)))
|
||||
|
||||
LJ_FUNCA int lj_tab_next(lua_State *L, GCtab *t, TValue *key);
|
||||
LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user