348 Commits
v3 ... v2.6.0

Author SHA1 Message Date
Tixx
77f3375658 Bump version to v2.6.0 2025-09-16 16:38:55 +02:00
Tixx
ae6e5b51bf User folder parsing updates (#208)
This PR adds support for the changes made to the BeamNG userfolder path
location.
1. Registry check for userfolder removed
2. New ini file is checked for userfolder
3. Ini parser now supports global keys

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-09-16 16:36:07 +02:00
Tixx
8a0f87f476 Remove registry check and add support for new ini file 2025-09-16 16:11:26 +02:00
Tixx
33b2030f97 Support global keys in ini 2025-09-16 16:10:16 +02:00
Tixx
5b2eb0a1a0 Change to execution paths to binary paths (#200)
Previously, it used argv[0] for the execution path, which is fine in
most cases, but in my case, it is not.
The thing is, I use NixOS, and I have created a Nix module for BeamMP.
When running BeamMP-Launcher, it tries to check for updates, and fails
because of the SHA hash.
There are other ways around this, such as setting the execution
directory, but I think this is a far clearer approach

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-08-02 19:38:18 +02:00
Vali0004
f27d3c6120 Fix bug with BP and not having a trailing slash by default 2025-08-02 00:21:40 -04:00
Vali0004
7a4b24d616 Change to canonical paths for executable paths 2025-08-02 00:14:37 -04:00
Tixx
b6b0e4ba3e Refine updating (#201)
This PR makes the launcher update more reliable by downloading the
update to a "new_BeamMP-Launcher.exe" file, instead of the launcher
renaming itself to a backup (effectively bricking itself and the
shortcut) and then hoping the download doesn't fail.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-07-27 01:58:06 +02:00
Tixx
a87aa7230a Make null termination in hex encoding more clear 2025-07-27 01:07:23 +02:00
Tixx
b9cc025083 Check hashes after downloading 2025-07-25 23:50:16 +02:00
Tixx
c0ed056440 Fix for backup failing when it's in use
The backup file may still be in use by older launcher versions (v2.0.71) if they update
2025-07-17 14:33:25 +02:00
Tixx
e6e5bf8327 Fix launcher update to delete backup after download 2025-07-17 14:32:17 +02:00
Tixx
e7cfb6e406 Add Debian legacy Steam installation path (#198)
Current Steam installations seem to have a much cleaner filesystem
layout on Debian while older ones look quite different.

Older Debian installations ~/.steam/root points to ~/.steam while newer
ones point to ~/.steam/debian-installation and hence BeamMP cannot find
integrity.json. 'steamapps' is at ~/.steam/debian-installation in newer
installations.

On the older installations, 'steamapps' is at ~/.steam/steam/steamapps.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-07-09 11:12:11 +02:00
Markus Ingalsuo
185818d174 Add Debian legacy Steam installation path
Current Steam installations seem to have a much cleaner filesystem
layout on Debian while older ones look quite different.

Older Debian installations ~/.steam/root points to ~/.steam while newer
ones point to ~/.steam/debian-installation and hence BeamMP cannot
find integrity.json. 'steamapps' is at ~/.steam/debian-installation in
newer installations.

On the older installations, 'steamapps' is at ~/.steam/steam/steamapps.

Signed-off-by: Markus Ingalsuo <markus.ingalsuo@gmail.com>
2025-07-09 11:34:45 +03:00
Tixx
406c79ef82 Bump version to v2.5.1 2025-07-08 13:24:32 +02:00
Tixx
f104451bb9 Switch Invalid INI line log to debug (#196)
By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-07-05 20:24:43 +02:00
Tixx
d52def2114 Make new CheckVer & GetEN compatible with linux (#195)
Fixes issues for linux that came from PR #167 

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-07-03 23:29:07 +02:00
Tixx
d71757b56c Switch Invalid INI line log to debug 2025-06-29 12:56:24 +02:00
Tixx
f7d3fcf925 Make new CheckVer & GetEN compatible with linux 2025-06-29 10:07:34 +02:00
Tixx
7bef6f35c2 Bump version to 2.5.0 2025-06-28 20:21:17 +02:00
Tixx
b64d645f73 Switch to wstring for paths on windows (#167)
This PR changes everything relating to file system paths to use
std::wstring instead of std::string. This allows for non-latin
characters to be in the user's path, for example in their windows
username.

- [x] Convert windows code to use wstring
- [x] Fix linux build
- [x] Fix hashing

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-06-28 19:25:13 +02:00
Tixx
1780133569 Include assert 2025-06-25 14:29:29 +02:00
Tixx
c89afdf477 Check
Co-authored-by: SaltySnail <51403141+SaltySnail@users.noreply.github.com>
2025-06-24 22:17:14 +02:00
Tixx
9d44146224 Regex assert
Co-authored-by: SaltySnail <51403141+SaltySnail@users.noreply.github.com>
2025-06-24 22:16:17 +02:00
Tixx
a5c02217fa Update ini parse check formatting
Co-authored-by: SaltySnail <51403141+SaltySnail@users.noreply.github.com>
2025-06-20 23:04:07 +02:00
Tixx
303fc55d94 Fix syntax error 2025-06-19 18:13:46 +02:00
Tixx
5f1e7c6409 Fix resources dir log message for linux 2025-06-19 18:07:59 +02:00
Tixx
8025c0884f Fix download path generation 2025-06-19 17:56:59 +02:00
Tixx
51d096deac Check if BeamMP.zip exists before hashing 2025-06-08 14:01:48 +02:00
Tixx
9c53f86593 Convert GetGamePath() to fs::path 2025-06-08 14:01:23 +02:00
Tixx
e0257e9526 Update NewSyncResources logs to use wstring 2025-06-08 13:51:16 +02:00
Tixx
8b96ffb098 Fix .git folder check and GetGamePath() 2025-06-08 13:45:09 +02:00
Tixx
6c740e2562 Fix merge 2025-06-08 13:34:15 +02:00
Tixx
06c741edc5 Fix wstring for windows and add crossplatform code for fs strings 2025-06-08 13:34:15 +02:00
Tixx
5e448dc34f Switch to wstring for paths on windows 2025-06-08 13:34:15 +02:00
Tixx
676084f283 Implement DeleteDuplicateMods option (#190)
Adds `DeleteDuplicateMods` option to the launcher config which, well,
deletes mods with the same name if their hashes mismatch. Useful for
development where client mod hashes can frequently change.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-06-08 12:56:23 +02:00
Tixx
a8cd208208 Make duplicate mod detection more readable
Co-authored-by: SaltySnail <51403141+SaltySnail@users.noreply.github.com>
2025-06-08 12:37:35 +02:00
Tixx
2529146d5a Implement DeleteDuplicateMods option 2025-06-08 12:37:32 +02:00
Tixx
8d641f326d Check if unpacked BeamMP has a .git folder before deleting it (#193)
This PR makes it so that the launcher will first check for the presence
of a .git folder before deleting the unpacked BeamMP directory.
This is useful when you're working on the BeamMP mod and you
accidentally start the launcher without dev mode. (This has happened to
me more times than I would like to admit.)

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-06-07 20:07:23 +02:00
Tixx
5af9f5da36 Show cached mods in download progress (#189)
This PR adds cached mods to the "Loading resources" pop-up in-game and
makes it so that the count is actually right.
This PR also fixes the mod protection message because for some reason I
forced it to be always off 😁.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-06-07 20:05:52 +02:00
Tixx
baba0ad026 Check if unpacked BeamMP has a .git folder before deleting it 2025-06-07 17:50:20 +02:00
Tixx
b1ebcfc18d Fix mod protection message 2025-05-27 22:12:07 +02:00
Tixx
187ef3b24f Show cached mods being loaded in download progress 2025-05-27 22:09:52 +02:00
Tixx
943889d588 Fix mod downloading progress 2025-05-27 22:08:50 +02:00
Tixx
edbd99f389 Added CLI argument for user-path (#148)
Simple addition to the CLI args. It could probably do with some
validation, ie; making sure it ends in a slash.

cc: @WiserTixx
2025-05-05 23:47:11 +02:00
Tixx
0341d401e7 Download check (#184)
This PR makes it so that the mod hash and download confirmation are
verified before proceeding.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-05-05 23:46:32 +02:00
Tixx
da84d62391 Notify user about missing protected mods (#183)
Launcher implementation for
https://github.com/BeamMP/BeamMP-Server/pull/430. This PR checks if mods
are protected, and if a mod is missing the launcher will notify the user
about it and give them instructions on how to resolve it.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-05-05 23:46:14 +02:00
Tixx
cc6167cd2e Bump version 2025-05-03 22:20:55 +02:00
Tixx
d3263acead Log corrupted download confirmation 2025-05-01 20:54:28 +02:00
Tixx
4de0bc9a40 Check download confirmation packet 2025-05-01 20:47:16 +02:00
Tixx
25a1061700 Verify mod hash after downloading 2025-05-01 20:42:01 +02:00
Tixx
f193c25de6 Switch to using INI parser for startup.ini file 2025-04-27 23:35:39 +02:00
Tixx
efe9f5b614 Add INI parser and function to expand env vars 2025-04-27 23:35:11 +02:00
Tixx
6244fdafc6 Use std::filesystem::operator/ instead of string concat 2025-04-26 19:45:10 +02:00
Tixx
ca93effb7d Update --user-path error message
Co-authored-by: Lion <development@kortlepel.com>
2025-04-26 18:46:15 +02:00
Tixx
f9d347bd9b Look for a userfolder specficied in the game's ini config 2025-04-26 18:42:41 +02:00
Tixx
a63f1bd27c Check if user path argument exists 2025-04-26 18:42:40 +02:00
Tyler Hoyt
ffc36e7f3d Added cli option for user-path 2025-04-26 18:42:31 +02:00
SaltySnail
e216b6ec06 Get error code when the game fails to launch on windows (#179)
This PR logs the error `CreateProcessA` returns when failing on windows.
This can help with figuring out why the launcher `Failed to Launch the
game!`

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-04-19 21:43:41 +02:00
Tixx
6597fe5e26 Rename windows api variable 2025-04-19 21:23:51 +02:00
Tixx
2fa5d69369 Link to the docs (#181)
Link to the docs instead

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-04-05 12:45:22 +02:00
O1LER
fec80e2c67 Link to the docs 2025-04-05 12:04:57 +02:00
Tixx
dc78883451 Notify user about missing protected mods 2025-04-01 09:09:49 +02:00
Tixx
fa8627a22b Fix recv return type and better download error handling (#178)
Fixes the recv return value type. This PR corrects the recv return value
type from `int32_t` to `int`. Casting the return value from `int` to
`int32_t` (Currently the case, changed by this pr) would in some cases,
if the transmitted packet was large enough, flip the value causing it to
be a high negative number, which recv will never return. This happens
frequently when downloading big mods over a fast connection.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-03-29 20:18:19 +01:00
Tixx
dd5256ae22 Increase download speed calculation precision 2025-03-29 00:19:25 +01:00
Tixx
e24cbf61bb Only fail on socket error or connection closed 2025-03-29 00:19:24 +01:00
Tixx
472e2d16b6 Fix recv return type and better download error handling 2025-03-29 00:19:24 +01:00
Tixx
ae650cc142 Get error code when the game fails to launch on windows 2025-03-28 23:16:37 +01:00
Tixx
ad7177bec8 Include chrono (#176)
By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-03-23 22:38:20 +01:00
Tixx
a4005c5876 Include chrono 2025-03-15 23:06:49 +01:00
Tixx
a3ad6f8700 Properly handle the futures (#172)
This PR makes it so that the std::async calls are actually asynchronous.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-03-08 22:29:08 +01:00
Tixx
d3bddb0203 Properly handle the future 2025-02-23 22:04:15 +01:00
Tixx
9e93fa35fa Bump version 2025-01-21 22:36:40 +01:00
Tixx
8373a70c4b Mod download improvements (#162)
This PR adds multiple features relating to mod downloads.
1. With this PR the launcher will convert old style mods (without hash)
to new style mods (with hash). This is so people don't have to
re-download all of their mods after joining a server which was
previously on a version below 3.6.0
2. This PR will save the last used date of mods in a JSON file in the
caching directory. This will allow for smart deletion of cached mods

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-01-18 22:56:33 +01:00
Tixx
d52a791dd9 Create mods.json if its missing 2025-01-18 22:29:49 +01:00
Tixx
08a6f9a093 Log current and backend version (#169)
By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-01-18 21:13:54 +01:00
Tixx
e5e40e186b Server info (#161)
Adds an `I` packet to the core handler, which allows the mod to use the
newly added [information packet
](https://github.com/BeamMP/BeamMP-Server/pull/382) in the server.
Usage:
Mod sends `I0.0.0.0:0000` and the launcher will send either
`I0.0.0.0:0000;` back if something went wrong, or `I0.0.0.0:0000;{Server
information JSON}` if it succeeded.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-01-18 20:52:44 +01:00
Tixx
bfbff52cb1 Log current and backend version 2025-01-12 23:17:23 +01:00
Tixx
8d4ba6f158 Implement size header for info packet 2025-01-12 16:57:33 +01:00
Tixx
a5d450b680 Raise buffer and remove timeout 2025-01-11 22:13:12 +01:00
Tixx
f4e985976f Strip packet letter in log 2025-01-11 21:55:08 +01:00
Tixx
db9ec53a6e Up curl connection timeout to 2 minutes (#160)
In some cases it can take longer than 10 seconds to connect to the
backend, so in this PR I've raised the limit to 2 minutes.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-01-11 21:54:35 +01:00
Tixx
f9b2edd410 Better curl debug (#165)
This PR makes it so the launcher logs curl's error description.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-01-11 21:51:13 +01:00
Tixx
333a95262b Check port and timeout recv 2025-01-11 21:50:39 +01:00
Tixx
e53885a8a8 Raise http get timeout to 2 minutes 2025-01-11 21:45:06 +01:00
Tixx
c22ea1e85d Fix typo in README.md (#166)
Fix non-critical typo in README:md

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2025-01-08 16:41:24 +01:00
O1LER
f8ea9bd8a3 Fix typo in README.md 2025-01-08 16:38:29 +01:00
Tixx
ad8eab3d66 Log error buffer 2024-12-29 16:39:56 +01:00
Tixx
e880da5cf9 Up curl connection timeout to 2 minutes 2024-12-25 00:54:19 +01:00
Tixx
d14b64c652 Fix linux build 2024-12-25 00:07:13 +01:00
Tixx
649514ca1a Save mod usage date 2024-12-24 13:53:50 +01:00
Tixx
a8a4dfb77c Fixed GameDir location issues. (#152)
I couldn't launch the game without this.

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2024-12-23 23:00:47 +01:00
Tixx
7149075d53 Implement core server information packet 2024-12-22 23:56:29 +01:00
Tixx
c485fba26b Change an easily confusable warning to debug 2024-12-22 12:13:59 +01:00
Tixx
d35567dd47 Look for new mods in the old format 2024-12-22 12:07:25 +01:00
Winos
f2b86cd5a0 Improved error handling as requested. 2024-12-16 09:10:54 -03:00
Tixx
3e7d16a8e8 Update Check for Game Files on Native Linux (#92)
Beforehand, the launcher would check only if the game directory existed.
This would lead to an error if the game was moved through Steam since
Steam leaves the BeamNG.Drive directory behind. Now it checks for to see
if integrity.json is inside. I also removed some commented out code I
seem to have left behind when I was porting it.

I agree to this code (and the whole port to native Linux since the #63
was locked and I couldn't agree there) being licensed under AGPL 3.
2024-12-14 20:47:58 +01:00
Tixx
03748d096f Switch to AGPL-3.0 (#86)
LOCKED until:
- [ ] Review each individual file for third party licenses
- [ ] Implement AGPL headers into each file
- [ ] Get confirmation from all contributors/copyright owners to make
the license change
- [ ] Eventually figure out bits of code of contributors that either
dont agree to the license change or that are unresponsive
2024-12-14 20:44:20 +01:00
Tixx
096d07fe9b Update build instructions (#156)
Update build instructions

Adresses both #155 and #153 

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2024-12-14 18:19:06 +01:00
O1LER
e7a0325e70 Add vcpkg to einstructions 2024-12-11 14:08:36 +01:00
PoorPockets McNewHold
7f627aaf92 Add missing vcpkg package for Fedora
```
BeamMP-Launcher on  master via △ v3.30.5 
 ❯ sudo dnf group info "Development Tools" 
Dernière vérification de l’expiration des métadonnées effectuée il y a 0:48:01 le mer. 11 déc. 2024 08:39:18.
Groupe : Outils de développement
 Description : Ces outils comprennent des outils de développement principaux comme git et cvs.
 Paquets obligatoires :
   gettext
 Paquets par défaut :
   diffstat
   doxygen
   git
   patch
   patchutils
   subversion
   systemtap
 Paquets optionnels :
   buildbot
   colordiff
   cvs
   cvs2cl
   cvsps
   darcs
   dejagnu
   expect
   gambas3-ide
   git-annex
   git-cola
   git2cl
   gitg
   gtranslator
   highlight
   lcov
   manedit
   meld
   monotone
   myrepos
   nemiver
   qgit
   quilt
   rapidsvn
   rcs
   robodoc
   scanmem
   subunit
   svn2cl
   tig
   tortoisehg
   translate-toolkit
   utrac
```
vcpkg isn't part of the Development Tools group on Fedora.
2024-12-11 09:28:56 +01:00
Winos
63aee03969 Update BeamNG.cpp
As requested:
- Changed 'string' variables that referred to paths to 'filesystem'.
- Added error log for when a valid 'GameDir' isn't found.

Also readded error log for when 'libraryfolders.vdf' is missing for better contextualization for the 'basic_string::_M_replace_aux' error (the code doesn't reach the GameDir segment when that file is not found).
2024-12-10 20:10:07 -03:00
Tixx
46e6fda26e Update license header 2024-12-07 11:26:09 +01:00
Lion Kortlepel
87c7edf404 fixup readme 2024-12-07 11:12:18 +01:00
Lion
f4fcbd63f5 Update README.md 2024-12-07 11:11:28 +01:00
Lion
7f1072b7c2 Create LICENSE 2024-12-07 11:10:51 +01:00
Winos
89327b8e20 Update src/Security/BeamNG.cpp
Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com>
2024-12-06 15:03:25 -03:00
Winos
ebf1579ce4 Update src/Security/BeamNG.cpp
Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com>
2024-12-06 15:03:19 -03:00
Winos
a06470cb70 Update src/Security/BeamNG.cpp
Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com>
2024-12-06 15:02:07 -03:00
Winos
80a3feb349 Update src/Security/BeamNG.cpp
Co-authored-by: Tixx <83774803+WiserTixx@users.noreply.github.com>
2024-12-06 15:02:00 -03:00
Tixx
f2166ff8c6 Add linux building instructions (#149)
- Do we need to mention that vcpkg should be installed in the first
place?
- Do we need to specify what the difference between release and debug
builds is?
- Are there any other prerequisites for building on windows?

---

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion.
I declare that I fully understand all code I pushed into this PR, and
wrote all this code myself and own the rights to this code.
2024-12-06 17:34:05 +01:00
Winos
ec1a09bbcb Fixed GameDir localization issues.
I couldn't launch the game without this.
2024-12-05 03:56:13 -03:00
Tixx
811fe41afb Update CMakeLists.txt to fix linux compilation (#151)
Fixed the Cmake lists file so it properly detects linux-based systems.
thats all. :3

By creating this pull request, I understand that code that is AI
generated or otherwise automatically generated may be rejected without
further discussion. I declare that I fully understand all code I pushed
into this PR, and wrote all this code myself and own the rights to this
code.
2024-12-03 13:30:15 +01:00
FirewallDaProtogen
c518a036ed Update CMakeLists.txt 2024-12-03 03:51:32 -05:00
O1LER
d8c1af4ac2 Add linux building instructions 2024-11-14 21:38:33 +01:00
Lion
00bd5be4d0 add PR template 2024-11-13 16:20:54 +01:00
Tixx
dff2f2712b Bump version 2024-11-07 22:12:20 +01:00
Lion
3effe0d4de log zlib error message and regex fix (#146) 2024-11-07 22:05:40 +01:00
Tixx
d58ff960ec Fix github regex 2024-11-07 21:39:18 +01:00
Tixx
f67f8573e0 Log zlib error messages 2024-11-07 21:36:38 +01:00
Lion
8a8e0be1a1 Print message from auth (#141) 2024-11-05 10:32:39 +01:00
Tixx
e0041666ca Clarify and change auth message log 2024-11-05 10:26:10 +01:00
Tixx
ed686333ec Print message from auth 2024-11-05 10:15:10 +01:00
Lion
8938fd84ea Add beammp.gg to the list of allowed links (#143) 2024-11-02 23:29:40 +01:00
Tixx
bd4c9c34a9 Add BeamMP github to the list of allowed links 2024-11-02 22:33:26 +01:00
Tixx
8519e279a7 Add beammp.gg to the list of allowed links 2024-11-02 22:18:46 +01:00
Lion Kortlepel
54895eb1b0 bump version 2024-11-01 12:53:55 +01:00
Lion
1423c1193b Speed up response times by waiting for http requests on another thread. (#137)
If, for example, the client requests the serverlist multiple times and
then tries to login the launcher will first wait for those requests to
finish. Thereby putting the other core communication (such as login) on
hold.
2024-11-01 12:13:21 +01:00
Lion
288e76594d Fix port cli argument (#142)
Fixes --port and -p by proccessing the config file before the cli
arguments, before it would first set --port because it was passed and
then overwrite it with the value from the config. Also removed some
useless code related to cli args.
2024-11-01 12:11:26 +01:00
Tixx
4fdc3c4031 Fix --port 2024-10-20 16:59:00 +02:00
Tixx
708da44fec Remove unused code 2024-10-20 16:57:47 +02:00
Tixx
6b6e304cfd Switch to std::async 2024-10-18 19:23:53 +02:00
Tixx
06cb366bb5 Add mutex to CoreSend 2024-10-16 23:12:02 +02:00
Tixx
0b35f0484f put blocking http requests on another thread 2024-10-16 23:12:02 +02:00
Lion
9dbbd8298d Switch to only timeout on connection (#140) 2024-10-15 19:32:55 +02:00
Tixx
ca9dd1ae75 Switch to only timeout on connection 2024-10-14 20:29:19 +02:00
Lion
9ebd218856 Fix empty modlist (#136)
This PR fixes the launcher getting confused when the server sends an
empty mod list using the new downloading system.
Related server PR: https://github.com/BeamMP/BeamMP-Server/pull/377
2024-10-12 22:10:47 +02:00
Pranay Sanghai
43b02f0118 Update Check For Game Files
Beforehand, it would check only if the game directory existed. This would lead to an error if the game is moved through Steam since it leaves the BeamNG.Drive directory. Now it checks for integrity.json. I also removed some commented out code I left behind.
2024-10-12 21:15:10 +02:00
Tixx
d9874ce70e Make return from parsemodinfo look better 2024-10-12 21:12:12 +02:00
Tixx
423519f31e Only listen on localhost ipv4 (#134)
This avoids the firewall popup on windows.
2024-10-12 20:58:29 +02:00
Tixx
3f12bb757a Mod info logs and check for old format 2024-10-10 21:35:27 +02:00
Lion Kortlepel
7d52e44434 only listen on localhost ipv4 2024-10-10 16:14:16 +02:00
Tixx
4fbd25b551 Handle new modlist being empty but still valid 2024-10-09 19:41:38 +02:00
Tixx
3cf1a2e51b Add mod info debug log 2024-10-09 19:39:27 +02:00
Lion Kortlepel
49874fd633 Revert "remove 'D' socket initialization code"
This reverts commit 6a23518eff.
2024-10-09 18:00:43 +02:00
Lion Kortlepel
6a23518eff remove 'D' socket initialization code 2024-10-09 17:36:54 +02:00
Lion Kortlepel
3297b3e62e fix not recognizing empty mod lists on new mod list 2024-10-09 17:35:50 +02:00
Lion Kortlepel
76cfc47a2f log invocation 2024-10-07 00:43:25 +02:00
Lion Kortlepel
7b59cb6f87 fix various commandline argument related things 2024-10-07 00:33:43 +02:00
Lion Kortlepel
0eba745d4c remove silly license 2024-10-07 00:33:29 +02:00
Lion
259b21502e Add command-line options (#90)
This PR adds command-line options as outlined in #74 

Closes #74
2024-10-06 23:49:47 +02:00
Tixx
afac729505 Ixmplement game arguments for linux 2024-10-06 15:56:48 +02:00
Lion
f57ebb7a92 follow HTTP redirects (#133)
Follow HTTP redirects on HTTP Get and Post functions
2024-10-06 15:20:49 +02:00
snepsnepsnep
ace96b7e33 follow HTTP redirects 2024-10-05 23:45:50 +02:00
Lion Kortlepel
fcb51adcb8 bump version 2024-10-05 21:05:02 +02:00
Tixx
0c53ff4cd4 Pass game arguments to beamng on windows 2024-10-05 18:34:39 +02:00
Tixx
68a4d64387 Fix linux relauch 2024-10-05 18:08:25 +02:00
Tixx
5bdd8c11da Fix relaunch 2024-10-05 18:01:47 +02:00
Tixx
47681cda50 Let user know about update even if --no-update was specified 2024-10-05 18:01:36 +02:00
Tixx
c99fecfa1c Fix debug log 2024-10-05 17:26:14 +02:00
Tixx
d26e0320e4 Add back support for old dev argument with warning 2024-10-05 17:26:14 +02:00
Tixx
57422a6105 Add optional dev config value 2024-10-05 17:20:40 +02:00
Tixx
467c8dc584 Add no-update flag 2024-10-05 17:20:40 +02:00
Tixx
2ddb576e72 Log core port 2024-10-05 17:20:40 +02:00
Tixx
e242057583 Improve port cli flag 2024-10-05 17:20:40 +02:00
Tixx
06686688fc Move console clear to main to avoid clearing logs 2024-10-05 17:20:40 +02:00
Tixx
aca61886d0 add command-line options 2024-10-05 17:20:40 +02:00
Lion
768f11f6ec Add mod hashing, improve download protocol (#129) 2024-10-04 23:36:57 +02:00
Lion
7944e9dbe8 Switch to curl for Get and Post (#132)
Because we can. I got a segfault while testing but then it didn't happen
again, so I'm tempted to call it done.
2024-10-04 23:23:49 +02:00
Lion Kortlepel
0c68f91fb2 remove debug print 2024-10-04 23:22:50 +02:00
Lion
b8fdbc4ed9 Fix GetGamePath (#130)
Previously, the registry was used to get the local appdata folder for
the user folder. I've switched this over to a windows api function which
fixes some cases where the launcher wouldn't be able to find the appdata
folder in the registry.
2024-10-04 23:12:56 +02:00
Lion Kortlepel
85908e42d5 fix download code, error checking 2024-10-04 23:12:23 +02:00
Lion Kortlepel
5c77e60f29 remove mis-merged code 2024-10-04 23:04:30 +02:00
Lion Kortlepel
c74455e0fe switch to curl for Get and Post 2024-10-04 22:59:29 +02:00
Lion
dc13e4a03c remove extra return 2024-10-04 14:13:04 +02:00
Tixx
1d7eb64fe0 Get localappdata via winapi instead of registry 2024-10-03 22:42:49 +02:00
Lion Kortlepel
1676d4174e make mods not keep the hash when copying them 2024-09-29 02:36:41 +02:00
Lion Kortlepel
ad468a8971 remove debug prints 2024-09-29 02:04:39 +02:00
Lion Kortlepel
d3805f2cfd fix mod deleting misnamed mods 2024-09-29 01:57:15 +02:00
Lion Kortlepel
9f1cc15b15 fix bugs with new download 2024-09-29 01:15:57 +02:00
Lion Kortlepel
c0fb4e4ad6 implement support for new mod hashing and download 2024-09-29 00:33:15 +02:00
Lion
7600372ca1 Fix linux executable name after BNG0.33.2 (#126) 2024-09-28 16:51:02 +02:00
Lion
54cd5b5e0e Add additional SSL Verify logging (#127) 2024-09-28 16:50:30 +02:00
Mackenzie
ede6fcd7dd log SSL errors 2024-09-27 20:33:14 +01:00
Mackenzie
eaeacbd8de log non-200 status codes 2024-09-27 20:23:28 +01:00
O1LER
0ffed00bcb rename linux executable for bng0.33.2 2024-09-27 17:48:46 +02:00
Lion
c0c3d6b30e Add download speed to UI (#125) 2024-09-24 21:59:01 +02:00
Lion
9c59a83f04 turn off stdout, stderr of the game on linux (#124) 2024-09-24 21:58:37 +02:00
Lion Kortlepel
95436cb073 turn off stdout, stderr of the game on linux 2024-09-24 21:56:55 +02:00
Lion Kortlepel
cbb5502a40 send download speed to game UI, bump version to 2.1.4 2024-09-24 21:50:09 +02:00
Lion Kortlepel
d6dfe85f69 add download speed to ingame ui 2024-09-24 21:10:10 +02:00
Tixx
ae9af1470c Removal invalid comma causing the default config to be broken (#123) 2024-09-24 12:47:20 +02:00
Tixx
9255c70b0b Removal invalid comma 2024-09-24 12:38:24 +02:00
Lion Kortlepel
53c514ecc6 bump to 2.1.3 2024-09-23 23:13:51 +02:00
Lion Kortlepel
e348d59a7e fix linux executable name 2024-09-23 23:13:34 +02:00
Lion
244d27341f Fix release actions (#122) 2024-09-23 22:49:33 +02:00
Lion Kortlepel
3a55b62907 remove release action 2024-09-23 22:49:03 +02:00
Lion
0c3ae43910 Add CachingDirectory config setting to cache mods elsewhere (#121)
also moved cls/clear to the beginning, idk wtf it was doing in there.
2024-09-23 22:45:21 +02:00
Lion Kortlepel
8436586566 print version on startup
🚀
2024-09-23 22:43:32 +02:00
Lion Kortlepel
19d1245379 catch errors when the custom caching directory is not accessible
🧯
2024-09-23 22:39:44 +02:00
Lion
470eeac821 Add better error handling (#119) 2024-09-23 22:34:19 +02:00
Lion
9c6aa86e68 Add print to inform the user that they must keep the window open (#120) 2024-09-23 22:33:54 +02:00
Lion Kortlepel
1362471657 add CachingDirectory config setting to cache mods elsewhere
also moved cls/clear to the beginning, idk wtf it was doing in there.
2024-09-23 22:31:58 +02:00
Lion Kortlepel
aa46b454e2 add print to inform the user that they must keep the window open 2024-09-23 22:12:00 +02:00
Lion Kortlepel
02465c529d add more logging to exit 2024-09-23 22:08:45 +02:00
Lion Kortlepel
c68cbf8946 remove unused """security""" code 2024-09-23 22:04:34 +02:00
Lion Kortlepel
46542c1dce always log debug to Launcher.log 2024-09-23 22:00:41 +02:00
Lion Kortlepel
97f58dd413 add better error handling to main() 2024-09-23 21:58:27 +02:00
Lion
4bedfc8e96 Little Itsy Bitsy TCP fixes (#118) 2024-09-23 21:46:11 +02:00
Lion Kortlepel
cd17df5cc2 add more debug statements, wait for threads before shutting down 2024-09-22 21:37:52 +02:00
Lion Kortlepel
0b589a74c9 refactor tcp receive to be less weird 2024-09-22 20:31:25 +02:00
Lion Kortlepel
1260515a40 fix crash when cancelling download 2024-09-22 20:20:31 +02:00
Lion
007cd6573e Refactor downloading (#116)
The way it was done was so horrid, it was not only impossible to debug,
with TODO comments saying it sucks, and other shit like that, but it was
also just full of data races. You can rest easy however - I left most of
the data races in there <3 For nostalgia (totally not because it's a
massive pain to fix that).

We now do single-threaded download, which can not only saturate my 100
Mbit/s line without any hickups, it can also go up to ~600000 Mbit/s for
localhost transfers :) So I think it's fine.
2024-09-22 20:04:45 +02:00
Lion
7b022f9907 Add --skip-ssl-verify cli option (#117)
This is a temporary fix for if anyone has issues with SSL certificate
validation. The use of this must come with the disclaimer that,
obviously, this bypasses the security that SSL gives entirely. Anyone
could MITM you at that point. Don't use, basically.
2024-09-22 19:56:43 +02:00
Lion Kortlepel
96c9c89238 add extra layer of checks for data races in download
yeah
2024-09-22 19:52:52 +02:00
Lion
b4949af1d7 Check 'User Shell Folders' (#111)
this PR is a continuation of #69
2024-09-22 19:47:50 +02:00
Lion
85086909a6 Merge pull request #108 from WiserTixx/implement-mods-warning
Implement mods warning
2024-09-22 19:46:34 +02:00
Lion Kortlepel
79209219dd remove extraneous game user path print 2024-09-22 19:42:55 +02:00
Lion Kortlepel
18e1b7a2bb add --skip-ssl-verify cli option 2024-09-22 19:42:00 +02:00
Lion Kortlepel
a5766639d6 add back user path print
Thanks @WiserTixx for finding a good place for it
2024-09-22 19:29:39 +02:00
Lion Kortlepel
191fbf083d fix stupid microsoft macro <3 2024-09-22 19:06:46 +02:00
Lion Kortlepel
8c4342853a refactor downloading
The way it was done was so horrid, it was not only impossible to debug,
with TODO comments saying it sucks, and other shit like that, but it was
also just full of data races. You can rest easy however - I left most of
the data races in there <3 For nostalgia (totally not because it's a
massive pain to fix that).

We now do single-threaded download, which can not only saturate my 100
Mbit/s line without any hickups, it can also go up to ~600000 Mbit/s for
localhost transfers :) So I think it's fine.
2024-09-22 18:52:50 +02:00
Tixx
3937ac1ae7 Fix joining 2024-09-14 22:17:21 +02:00
Tixx
a128099619 Patch up removal of while loop in Core 2024-09-14 22:17:21 +02:00
Tixx
deed24f6e8 Fix client lua error 2024-09-14 22:17:21 +02:00
Tixx
ac2db7c73f Remove now unused variable 2024-09-14 22:17:21 +02:00
Tixx
06db6d0341 Implement mod warning 2024-09-14 22:17:21 +02:00
Deer McDurr
2d43e11e96 Merge pull request #114 from WiserTixx/action-fix
Fix github actions
2024-09-14 22:14:53 +02:00
Tixx
8911158f81 Fix actions 2024-09-14 22:03:52 +02:00
20dka
a714dc3188 fix windows build and implement suggestion from lionkor 2024-09-08 16:42:03 +02:00
yeranya
29445f65ce check 'User Shell Folders' key in addition to 'Shell Folders' 2024-09-08 16:24:58 +02:00
Deer McDurr
48be292850 Merge pull request #103 from purifiedfr/readme-build-guide
Update the Build guide in README
2024-09-08 16:00:06 +02:00
purified
2397f45d3f Add the guide on how to clone the repository with the evpp submodule 2024-09-08 15:57:15 +02:00
purified
d1fb67f1f0 Update the Build guide in README
Add instructions for building in Release mode
Add the reminder to change the vcpkg location
Add the reminder to run the commands in the root of the project
2024-09-08 15:57:15 +02:00
Deer McDurr
eae6d11476 Merge pull request #110 from WiserTixx/improve-http-proxy
HTTP proxy improvements, avatar endpoint
2024-09-08 14:46:49 +02:00
Tixx
452fc1e484 Move HTTP Proxy and remove and relocate duplicate code 2024-09-07 22:35:27 +02:00
Tixx
de3888618a Safety improvements 2024-09-07 22:00:51 +02:00
Tixx
4678701f42 HTTP proxy improvements
Adds the avatar endpoint and adds the possibility to easily add others
2024-09-07 21:19:42 +02:00
Deer McDurr
7481ba4539 Merge pull request #109 from WiserTixx/allow-patreon-link
Add BeamMP patreon to the allowed links
2024-09-07 20:53:40 +02:00
Tixx
d791e2ac92 Add BeamMP patreon to the allowed links 2024-08-22 22:09:02 +02:00
Lion
a60ff48c08 Merge pull request #105 from WiserTixx/id-from-auth
Send id from auth to game
2024-08-17 20:34:19 +02:00
Lion
da3b49aa12 Merge pull request #106 from WiserTixx/fix-http-proxy-ub
Fix UB which was causing the http proxy to crash
2024-08-17 20:32:59 +02:00
Tixx
e505874af9 Send id from auth to game 2024-08-11 11:39:14 +02:00
Tixx
2f0a9fba99 move macro definition to cmakelist 2024-08-10 23:22:17 +02:00
Lion Kortlepel
b034072027 fix potential UB in decompression 2024-06-23 23:04:55 +02:00
Lion Kortlepel
f94b9adf7a print game's U S E R path 2024-06-22 23:26:10 +02:00
Lion Kortlepel
c95178ea59 dont auto-update in dev mode 2024-06-22 23:20:46 +02:00
Lion Kortlepel
1f7c498bd9 fix compiler error in decomp 2024-06-22 23:05:01 +02:00
Lion Kortlepel
e46d4b2f0e Merge branch 'performance-improvements' 2024-06-22 23:01:15 +02:00
Lion Kortlepel
f2b34543f9 switch to compression with limit at 30 MB 2024-06-22 22:48:00 +02:00
Lion Kortlepel
d32da036bc fix mod name bug 2024-06-21 17:30:47 +02:00
Lion Kortlepel
8b0f4f99f6 use thread_local static buffer to receive into, null term manually 2024-06-19 16:53:17 +02:00
Lion Kortlepel
17e887442c avoid a substr() which costs us ~20% of runtime performance 2024-06-19 16:18:11 +02:00
Lion Kortlepel
fc454cd11e avoid creating a thread every packet 2024-06-19 15:53:49 +02:00
Lion
e0e2607632 Merge pull request #96 from BeamMP/finalize-linux-merge
Finalize linux merge
2024-06-18 09:57:24 +02:00
Lion Kortlepel
25f28e7fee add common runtime files to gitignore 2024-06-18 09:57:05 +02:00
Lion Kortlepel
ba9719ed67 fix auth packet prefix 2024-06-18 09:46:33 +02:00
Lion Kortlepel
bb04d1bfe1 remove self update on linux for now 2024-06-18 08:51:23 +02:00
Lion Kortlepel
82e58e6513 add toolchain to linux build
oops
2024-06-17 22:36:15 +02:00
Lion Kortlepel
274a1dac7c fix workflows vcpkg version 2024-06-17 22:30:26 +02:00
Lion Kortlepel
ae7f8f44e3 re-implement the website launch feature for linux 2024-06-17 22:16:17 +02:00
Lion Kortlepel
a82b9fb36f reformat 2024-06-17 22:01:15 +02:00
Lion Kortlepel
3488136ca4 add clang format 2024-06-17 21:59:59 +02:00
Lion Kortlepel
05ffa0b638 Merge branch 'linux' 2024-06-17 21:57:41 +02:00
Lion
942cc78406 remove debug print 2024-06-15 22:24:19 +02:00
Lion
46690b5bbf Merge pull request #79 from BeamMP/hotfix-stuff
Fixup various bits
2024-06-15 21:46:07 +02:00
Lion
cc4e322065 Merge pull request #88 from saile515/fix-input-linux
Fix input not working on Linux
2024-05-29 11:13:05 +02:00
saile515
915c05c57c fix input not working on linux 2024-05-29 10:56:22 +02:00
Lion Kortlepel
adba66afb9 add http debug error logging 2024-03-22 12:19:18 +01:00
Lion Kortlepel
cc42a5e0ab add ssl verify debug logging in a few places 2024-03-22 11:34:14 +01:00
Lion Kortlepel
c8a1b77a54 remove discord 2024-03-22 11:23:49 +01:00
Lion Kortlepel
b9d252fd8a remove old stuff 2024-03-22 11:22:17 +01:00
Lion Kortlepel
2b02475fd4 add build instructions 2024-03-22 11:09:02 +01:00
Lion Kortlepel
8aa7a67100 add vcpkg.json 2024-03-22 11:07:30 +01:00
Lion Kortlepel
348090a127 fix perms on more source files
... wtf
2024-03-22 10:50:58 +01:00
Lion Kortlepel
c0df995e28 fix perms on all source files 2024-03-22 10:47:08 +01:00
Lion Kortlepel
8c9d3a5455 fix not returning error from Login, remove old code 2024-02-24 20:26:26 +01:00
Lion Kortlepel
9dcfa1dca4 set username or role to auth if they're empty (not set) 2024-02-24 20:26:26 +01:00
Lion Kortlepel
bd4cfe06b1 reset username and role on logout 2024-02-24 20:26:26 +01:00
Lion Kortlepel
9c7034e401 store username and role on key login as well 2024-02-24 20:26:26 +01:00
Lion Kortlepel
aeb167c1e8 forward user's role on login 2024-02-24 20:26:26 +01:00
Lion Kortlepel
7967ec38e8 bump version to *.85 2024-02-24 20:26:26 +01:00
Lion Kortlepel
250be2ccdc fix more breaking bug 2024-02-24 20:26:26 +01:00
Lion Kortlepel
6158069d4d fix game breaking bug 2024-02-24 20:26:26 +01:00
Lion Kortlepel
b2e5b8d2d3 print error when throwing exception in auth 2024-02-24 20:26:26 +01:00
Lion Kortlepel
5db1b48e07 Revert "debug print error in case of unexpected login error"
This reverts commit 68d64105de.
2024-02-24 20:26:26 +01:00
Lion Kortlepel
56dcfcc5ed debug print error in case of unexpected login error 2024-02-24 20:26:26 +01:00
Lion Kortlepel
7c1106a46a add username to auth packet 2024-02-24 20:26:26 +01:00
Anonymous275
9afdfd4d1b v2.0.84
- add Access-Control response headers
2023-12-16 14:30:35 +00:00
Anonymous275
c2f260a86c v2.0.84
- remove comment
2023-12-15 19:39:55 +00:00
Anonymous275
2781179b4b v2.0.84
- proxy tweaking
2023-12-15 19:38:47 +00:00
Anonymous275
3b479abf64 v2.0.84
- add hash check
- new routes for updates
- use C++ 20
2023-12-15 18:16:12 +00:00
Anonymous275
c731718f50 v2.0.84
- HTTP Proxy for backend.beammp.com
- Fix Attempt for mod loading, game detecting partial zip file
- Use nlohmann JSON
- Update vcpkg parameters and commit ID
- Add ability to open URL using default browser with filter
2023-12-15 17:38:47 +00:00
Anonymous-275
0fd0a9fe7e Merge remote-tracking branch 'origin/master' 2023-10-26 00:09:04 +01:00
Anonymous-275
302582bfe1 v2.0.83
- removed code that is no longer needed
2023-10-26 00:08:56 +01:00
gamingdoom
35ad09dd5f Remove extra newline 2023-10-17 21:01:38 -07:00
gamingdoom
8ed2921ec1 remove .vscode 2023-10-17 20:41:15 -07:00
gamingdoom
1bf7faa34d fix guest account issue and uppercase mods 2023-10-17 20:40:11 -07:00
gamingdoom
8ead91c527 Update release-build.yml 2023-10-17 19:31:40 -07:00
gamingdoom
5e602a651c Fix linux build artifact path 2023-10-17 19:18:48 -07:00
gamingdoom
0993b2a463 fix linux build name ... again 2023-10-17 19:16:17 -07:00
gamingdoom
73ada2b541 fix linux build name 2023-10-17 19:15:44 -07:00
gamingdoom
f9bd0967bc Add github actions Linux build 2023-10-17 19:14:54 -07:00
gamingdoom
16b13c074e remove debug symbols 2023-10-17 19:13:16 -07:00
gamingdoom
0a9a883ca4 fix windows build 2023-10-17 18:59:49 -07:00
gamingdoom
a91735531a linux build 2023-10-17 18:53:01 -07:00
gamingdoom
f98ff3f502 Update cmake-windows.yml 2023-10-17 18:38:59 -07:00
gamingdoom
5dfb5f3b88 works but linux build is broken and this is an old version of the source 2023-10-16 22:13:30 -07:00
gamingdoom
54e1beb548 rename network.h to network.hpp 2023-10-16 17:33:52 -07:00
Anonymous275
839bb48cd6 Merge pull request #58 from WhiteHusky/patch-1
Emit a useful message if cleaning the mods folder fails
2023-08-04 20:30:36 +01:00
Carlen White
c4ebdda1a4 Emit a useful message if cleaning the mods folder fails
The launcher complains if it can not delete a file when it's trying to clean the mods folder out. However the message it emits is unhelpful and does not offer a suggestion to what is going on.

This commit addresses this issue by telling the user what the launcher is trying to do and suggests checking if something is currently open in that directory. I figure not having to go into detail in *where* the folder is not necessary and (primarily) only happens if the user is inspecting the folder themselves and already knows where the folder is.
2023-07-02 23:02:14 -04:00
Anonymous275
d6b494c6c4 - release v2.0.82 2022-12-18 14:30:21 +00:00
Anonymous275
a80d4f5147 - quick fix for launcher crash 2022-12-18 14:29:38 +00:00
Anonymous275
811b04485c - try fix for github workflow 2022-12-18 13:20:20 +00:00
Simon Abed El Sater
a64fead653 update 2.0.81 2022-12-18 14:39:54 +02:00
Simon Abed El Sater
399461d1b1 remove version check 2022-12-18 14:39:28 +02:00
Anonymous275
ec5e8ed5b3 v2.0.80 2022-09-25 20:39:27 +03:00
Anonymous275
5655164e60 bump 2.0.80 2022-09-25 20:37:46 +03:00
Simon Abed El Sater
3d9b7c2d67 Merge pull request #49 from snepsnepsnep/master
Fix kick message for server 3.0+
2022-09-25 20:32:50 +03:00
snepsnepsnep
764e3ab5c1 Fix kick message for server 3.0+ 2022-09-25 19:26:46 +02:00
Simon Abed El Sater
3314362faf Merge pull request #48 from Mack29446/master
Decided by vote: Update BeamNG Version and remove Mod Delete warning & Delay
2022-09-25 01:18:58 +03:00
Mackenzie
e483f520db Bump launcher version
2.0.78 -> 2.0.79
2022-09-24 22:49:10 +01:00
Mackenzie
c92e32c0e1 Remove mod wipe warn and delay 2022-09-24 22:48:17 +01:00
Mackenzie
cb872f8a41 Update BeamNG Version 2022-09-24 22:46:38 +01:00
Anonymous275
0aae245054 release 2.0.78 2022-09-24 00:37:29 +03:00
Anonymous275
480a7d038f follow redirects if present 2022-09-24 00:37:04 +03:00
Anonymous275
f62f44d4c0 version 2.0.77 2022-09-20 22:27:26 +03:00
Anonymous275
e316b89fb1 bump 0.26 2022-09-20 22:26:51 +03:00
Anonymous275
3b2dbcac1b release 2.0.76 2022-09-05 03:23:15 +03:00
Anonymous275
d881c9faf6 release 2.0.75 2022-09-05 02:59:05 +03:00
Anonymous275
11d9375f36 fix invalid Key being used 2022-09-05 02:58:22 +03:00
Simon Abed El Sater
4207d7adcf Merge pull request #44 from snepsnepsnep/master
remove key if auth is unsuccessful
2022-09-05 02:40:50 +03:00
snepsnepsnep
832b1d66a0 remove key if auth is unsuccessful 2022-09-04 20:24:27 +02:00
Anonymous275
cd829f9f22 Update Startup.cpp
version 2.0.74
2022-08-12 12:14:31 +03:00
Anonymous275
f7c70eb6df Merge pull request #36 from Mack29446/master
Change serverlist request URL and Protocol
2022-08-12 12:11:22 +03:00
Mackenzie
01960f6470 Change serverlist request URL and Protocol 2022-08-11 20:27:26 +01:00
Anonymous275
f6065a1c00 Merge pull request #21 from Mack29446/master
Update version
2022-06-24 19:46:26 +03:00
Mackenzie
ba3b7f0ed0 Update version 2022-06-23 16:53:06 +01:00
Anonymous275
056eadbef2 Merge pull request #20 from Mack29446/master
Update version
2022-06-21 18:12:49 +03:00
Mackenzie
2bb2dc9040 Update version 2022-06-21 14:28:10 +01:00
Anonymous275
17553fd412 bump launcher version 2022-06-19 02:28:26 +03:00
Anonymous275
08c1c0f682 Merge pull request #19 from Mack29446/master
Update Version Number
2022-06-18 02:02:36 +03:00
Mackenzie
84959ae9c9 Update Version Number 2022-06-17 21:35:00 +01:00
Anonymous275
c90c102097 trying to fix github actions 2022-06-15 21:38:45 +03:00
Anonymous275
5b004426ce vcpkgGitCommitId update 2022-06-15 21:35:12 +03:00
Anonymous275
69c9060dd2 Update release-build.yml 2022-06-15 21:13:02 +03:00
Anonymous275
49870639ff Update cmake-windows.yml 2022-06-15 21:12:41 +03:00
Anonymous275
0843862af9 update for game version 0.25 2022-06-15 21:02:43 +03:00
185 changed files with 32464 additions and 33038 deletions

View File

@@ -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
...

6
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,6 @@
Please replace this text <-> with your PR description and leave the below declarations intact.
---
By creating this pull request, I understand that code that is AI generated or otherwise automatically generated may be rejected without further discussion.
I declare that I fully understand all code I pushed into this PR, and wrote all this code myself and own the rights to this code.

42
.github/workflows/cmake-linux.yml vendored Normal file
View 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

View File

@@ -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 cpp-httplib tomlplusplus easyloggingpp[no-defaultfile]'
vcpkgArguments: 'discord-rpc zlib nlohmann-json openssl cpp-httplib[openssl]'
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
vcpkgGitCommitId: '16ee2ecb31788c336ace8bb14c21801efb6836e4'
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

10
.gitignore vendored
View File

@@ -4,4 +4,12 @@ cmake-build-release
*.log
/*.sh
/*.obj
/*.exe
/*.exe
.cache/
.https_debug/
Launcher.cfg
Resources/
bin/
compile_commands.json
key
out/

3
.gitmodules vendored
View File

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

View File

@@ -1,63 +1,40 @@
cmake_minimum_required(VERSION 3.5)
project(BeamMP-Launcher)
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 20)
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})
#-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)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
add_compile_definitions(CPPHTTPLIB_OPENSSL_SUPPORT)
find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(minhook CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
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)
find_package(CURL REQUIRED)
add_executable(${PROJECT_NAME}
src/main.cpp
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_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 easyloggingpp)
else ()
target_link_libraries(${PROJECT_NAME} PRIVATE ${VcpkgRoot}/debug/lib/easyloggingpp.lib)
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 httplib::httplib)
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto ws2_32 httplib::httplib nlohmann_json::nlohmann_json CURL::libcurl)
elseif (UNIX)
find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE
ZLIB::ZLIB OpenSSL::SSL OpenSSL::Crypto CURL::libcurl)
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 CURL::libcurl)
endif(WIN32)
target_include_directories(${PROJECT_NAME} PRIVATE "include")

View File

@@ -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.

663
LICENSE
View File

@@ -1,2 +1,661 @@
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.
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

31
README.md Executable file → Normal file
View File

@@ -1,24 +1,23 @@
# 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.
## [Getting started](https://docs.beammp.com/game/getting-started/)
# Dependencies
## License
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.
BeamMP Launcher, a launcher for the BeamMP mod for BeamNG.drive
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
- [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
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
# Copyright
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
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.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

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

View File

@@ -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
View File

@@ -0,0 +1,21 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include "Logger.h"
#include "Utils.h"
#include <string>
class HTTP {
public:
static bool Download(const std::string& IP, const beammp_fs_string& Path, const std::string& Hash);
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;
};

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -1,115 +0,0 @@
///
/// Created by Anonymous275 on 12/26/21
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
///
#pragma once
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <httplib.h>
#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 StartProxy();
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();
const std::string& getProtocolVersion();
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{"3.0"};
static inline std::string FullVersion{Version + ".0"};
static inline std::string ProtocolVersion{"2.0"};
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 BackendProxy{};
std::thread DiscordRPC{};
std::string ConnectURI{};
std::string BeamVersion{};
std::string DiscordMessage{};
Server ServerHandler{this};
std::string TargetBuild{"default"};
httplib::Server HTTPProxy;
int ProxyPort{0};
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){};
};

View File

@@ -1,16 +1,24 @@
///
/// Created by Anonymous275 on 12/26/21
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
///
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <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);
void except(const std::wstring& toPrint);
void fatal(const std::wstring& toPrint);
void debug(const std::wstring& toPrint);
void error(const std::wstring& toPrint);
void info(const std::wstring& toPrint);
void warn(const std::wstring& toPrint);
std::string getDate();

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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{};
};

View File

@@ -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_;
};

View File

@@ -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();
};

View File

@@ -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"
};
}

View File

@@ -0,0 +1,57 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <filesystem>
#include <string>
#ifdef __linux__
#include "linuxfixes.h"
#include <bits/types/siginfo_t.h>
#include <cstdint>
#include <sys/ucontext.h>
#include <arpa/inet.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 uint64_t UDPSock;
extern uint64_t TCPSock;
extern std::string Branch;
extern std::filesystem::path CachingDirectory;
extern bool deleteDuplicateMods;
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);

31
include/Options.h Normal file
View File

@@ -0,0 +1,31 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <string>
struct Options {
#if defined(_WIN32)
std::string executable_name = "BeamMP-Launcher.exe";
#elif defined(__linux__)
std::string executable_name = "BeamMP-Launcher";
#endif
unsigned int port = 4444;
bool verbose = false;
bool no_download = false;
bool no_update = false;
bool no_launch = false;
const char* user_path = nullptr;
const char **game_arguments = nullptr;
int game_arguments_length = 0;
const char** argv = nullptr;
int argc = 0;
};
void InitOptions(int argc, const char *argv[], Options &options);
extern Options options;

8
include/Security/Game.h Normal file
View File

@@ -0,0 +1,8 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
extern unsigned long GamePID;

14
include/Security/Init.h Normal file
View File

@@ -0,0 +1,14 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <string>
void PreGame(const beammp_fs_string& GamePath);
std::string CheckVer(const std::filesystem::path& path);
void InitGame(const beammp_fs_string& Dir);
beammp_fs_string GetGameDir();
void LegitimacyCheck();
void CheckLocalKey();

View File

@@ -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
View File

@@ -0,0 +1,21 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include "Utils.h"
#include <compare>
#include <string>
#include <vector>
void InitLauncher();
beammp_fs_string GetEP(const beammp_fs_char* P = nullptr);
std::filesystem::path GetBP(const beammp_fs_char* P = nullptr);
std::filesystem::path GetGamePath();
std::string GetVer();
std::string GetPatch();
beammp_fs_string GetEN();
void ConfigInit();

294
include/Utils.h Normal file
View File

@@ -0,0 +1,294 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <cassert>
#include <filesystem>
#include <fstream>
#include <locale>
#include <map>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <regex>
#include <string>
#include <variant>
#include <vector>
#ifdef _WIN32
#define beammp_fs_string std::wstring
#define beammp_fs_char wchar_t
#define beammp_wide(str) L##str
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#define beammp_fs_string std::string
#define beammp_fs_char char
#define beammp_wide(str) str
#endif
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;
};
inline std::string ExpandEnvVars(const std::string& input) {
std::string result;
std::regex envPattern(R"(%([^%]+)%|\$([A-Za-z_][A-Za-z0-9_]*)|\$\{([^}]+)\})");
std::sregex_iterator begin(input.begin(), input.end(), envPattern);
std::sregex_iterator end;
size_t lastPos = 0;
for (auto it = begin; it != end; ++it) {
const auto& match = *it;
result.append(input, lastPos, match.position() - lastPos);
std::string varName;
if (match[1].matched) varName = match[1].str(); // %VAR%
else if (match[2].matched) varName = match[2].str(); // $VAR
else if (match[3].matched) varName = match[3].str(); // ${VAR}
if (const char* envValue = std::getenv(varName.c_str())) {
result.append(envValue);
}
lastPos = match.position() + match.length();
}
result.append(input, lastPos, input.length() - lastPos);
return result;
}
#ifdef _WIN32
inline std::wstring ExpandEnvVars(const std::wstring& input) {
std::wstring result;
std::wregex envPattern(LR"(%([^%]+)%|\$([A-Za-z_][A-Za-z0-9_]*)|\$\{([^}]+)\})");
std::wsregex_iterator begin(input.begin(), input.end(), envPattern);
std::wsregex_iterator end;
size_t lastPos = 0;
for (auto it = begin; it != end; ++it) {
const auto& match = *it;
result.append(input, lastPos, match.position() - lastPos);
std::wstring varName;
assert(match.size() == 4 && "Input regex has incorrect amount of capturing groups");
if (match[1].matched) varName = match[1].str(); // %VAR%
else if (match[2].matched) varName = match[2].str(); // $VAR
else if (match[3].matched) varName = match[3].str(); // ${VAR}
if (const wchar_t* envValue = _wgetenv(varName.c_str())) {
if (envValue != nullptr) {
result.append(envValue);
}
}
lastPos = match.position() + match.length();
}
result.append(input, lastPos, input.length() - lastPos);
return result;
}
#endif
inline std::map<std::string, std::variant<std::map<std::string, std::string>, std::string>> ParseINI(const std::string& contents) {
std::map<std::string, std::variant<std::map<std::string, std::string>, std::string>> ini;
std::string currentSection;
auto sections = Split(contents, "\n");
for (size_t i = 0; i < sections.size(); i++) {
std::string line = sections[i];
if (line.empty() || line[0] == ';' || line[0] == '#')
continue;
for (auto& c : line) {
if (c == '#' || c == ';') {
line = line.substr(0, &c - &line[0]);
break;
}
}
auto invalidLineLog = [&]{
debug("Invalid INI line: " + line);
debug("Surrounding lines: \n" +
(i > 0 ? sections[i - 1] : "") + "\n" +
(i < sections.size() - 1 ? sections[i + 1] : ""));
};
if (line[0] == '[') {
currentSection = line.substr(1, line.find(']') - 1);
} else {
std::string key, value;
size_t pos = line.find('=');
if (pos != std::string::npos) {
key = line.substr(0, pos);
key = key.substr(0, key.find_last_not_of(" \t") + 1);
value = line.substr(pos + 1);
if (currentSection.empty()) {
ini[key] = value;
} else {
std::get<std::map<std::string, std::string>>(ini[currentSection])[key] = value;
}
} else {
invalidLineLog();
continue;
}
key.erase(key.find_last_not_of(" \t") + 1);
value.erase(0, value.find_first_not_of(" \t"));
value.erase(value.find_last_not_of(" \t") + 1);
std::get<std::map<std::string, std::string>>(ini[currentSection])[key] = value;
}
}
return ini;
}
#ifdef _WIN32
inline std::wstring ToWString(const std::string& s) {
if (s.empty()) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), nullptr, 0);
if (size_needed <= 0) {
return L"";
}
std::wstring result(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), (int)s.size(), &result[0], size_needed);
return result;
}
#else
inline std::string ToWString(const std::string& s) {
return s;
}
#endif
inline std::string GetSha256HashReallyFastFile(const beammp_fs_string& filename) {
try {
EVP_MD_CTX* mdctx;
const EVP_MD* md;
uint8_t sha256_value[EVP_MAX_MD_SIZE];
md = EVP_sha256();
if (md == nullptr) {
throw std::runtime_error("EVP_sha256() failed");
}
mdctx = EVP_MD_CTX_new();
if (mdctx == nullptr) {
throw std::runtime_error("EVP_MD_CTX_new() failed");
}
if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestInit_ex2() failed");
}
std::ifstream stream(filename, std::ios::binary);
const size_t FileSize = std::filesystem::file_size(filename);
size_t Read = 0;
std::vector<char> Data;
while (Read < FileSize) {
Data.resize(size_t(std::min<size_t>(FileSize - Read, 4096)));
size_t RealDataSize = Data.size();
stream.read(Data.data(), std::streamsize(Data.size()));
if (stream.eof() || stream.fail()) {
RealDataSize = size_t(stream.gcount());
}
Data.resize(RealDataSize);
if (RealDataSize == 0) {
break;
}
if (RealDataSize > 0 && !EVP_DigestUpdate(mdctx, Data.data(), Data.size())) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestUpdate() failed");
}
Read += RealDataSize;
}
unsigned int sha256_len = 0;
if (!EVP_DigestFinal_ex(mdctx, sha256_value, &sha256_len)) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestFinal_ex() failed");
}
EVP_MD_CTX_free(mdctx);
std::string result;
for (size_t i = 0; i < sha256_len; i++) {
char buf[3];
sprintf(buf, "%02x", sha256_value[i]);
buf[2] = '\0';
result += buf;
}
return result;
} catch (const std::exception& e) {
error(beammp_wide("Sha256 hashing of '") + filename + beammp_wide("' failed: ") + ToWString(e.what()));
return "";
}
}
inline std::string GetSha256HashReallyFast(const std::string& text, const beammp_fs_string& filename) {
try {
EVP_MD_CTX* mdctx;
const EVP_MD* md;
uint8_t sha256_value[EVP_MAX_MD_SIZE];
md = EVP_sha256();
if (md == nullptr) {
throw std::runtime_error("EVP_sha256() failed");
}
mdctx = EVP_MD_CTX_new();
if (mdctx == nullptr) {
throw std::runtime_error("EVP_MD_CTX_new() failed");
}
if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestInit_ex2() failed");
}
if (!EVP_DigestUpdate(mdctx, text.data(), text.size())) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestUpdate() failed");
}
unsigned int sha256_len = 0;
if (!EVP_DigestFinal_ex(mdctx, sha256_value, &sha256_len)) {
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("EVP_DigestFinal_ex() failed");
}
EVP_MD_CTX_free(mdctx);
std::string result;
for (size_t i = 0; i < sha256_len; i++) {
char buf[3];
sprintf(buf, "%02x", sha256_value[i]);
buf[2] = '\0';
result += buf;
}
return result;
} catch (const std::exception& e) {
error(beammp_wide("Sha256 hashing of '") + filename + beammp_wide("' failed: ") + ToWString(e.what()));
return "";
}
}
};

12
include/Zlib/Compressor.h Normal file
View File

@@ -0,0 +1,12 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <span>
#include <vector>
std::vector<char> Comp(std::span<const char> input);
std::vector<char> DeComp(std::span<const char> input);

View File

@@ -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{};
};

File diff suppressed because it is too large Load Diff

25
include/linuxfixes.h Normal file
View File

@@ -0,0 +1,25 @@
/*
Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors.
Licensed under AGPL-3.0 (or later), see <https://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL-3.0-or-later
*/
#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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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))

View File

@@ -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))

View File

@@ -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))

View File

@@ -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));
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,164 +0,0 @@
/*
** Definitions for target CPU.
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
*/
#ifndef _LJ_TARGET_H
#define _LJ_TARGET_H
#include "lj_def.h"
#include "lj_arch.h"
/* -- Registers and spill slots ------------------------------------------- */
/* Register type (uint8_t in ir->r). */
typedef uint32_t Reg;
/* The hi-bit is NOT set for an allocated register. This means the value
** can be directly used without masking. The hi-bit is set for a register
** allocation hint or for RID_INIT, RID_SINK or RID_SUNK.
*/
#define RID_NONE 0x80
#define RID_MASK 0x7f
#define RID_INIT (RID_NONE|RID_MASK)
#define RID_SINK (RID_INIT-1)
#define RID_SUNK (RID_INIT-2)
#define ra_noreg(r) ((r) & RID_NONE)
#define ra_hasreg(r) (!((r) & RID_NONE))
/* The ra_hashint() macro assumes a previous test for ra_noreg(). */
#define ra_hashint(r) ((r) < RID_SUNK)
#define ra_gethint(r) ((Reg)((r) & RID_MASK))
#define ra_sethint(rr, r) rr = (uint8_t)((r)|RID_NONE)
#define ra_samehint(r1, r2) (ra_gethint((r1)^(r2)) == 0)
/* Spill slot 0 means no spill slot has been allocated. */
#define SPS_NONE 0
#define ra_hasspill(s) ((s) != SPS_NONE)
/* Combined register and spill slot (uint16_t in ir->prev). */
typedef uint32_t RegSP;
#define REGSP(r, s) ((r) + ((s) << 8))
#define REGSP_HINT(r) ((r)|RID_NONE)
#define REGSP_INIT REGSP(RID_INIT, 0)
#define regsp_reg(rs) ((rs) & 255)
#define regsp_spill(rs) ((rs) >> 8)
#define regsp_used(rs) \
(((rs) & ~REGSP(RID_MASK, 0)) != REGSP(RID_NONE, 0))
/* -- Register sets ------------------------------------------------------- */
/* Bitset for registers. 32 registers suffice for most architectures.
** Note that one set holds bits for both GPRs and FPRs.
*/
#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64
typedef uint64_t RegSet;
#else
typedef uint32_t RegSet;
#endif
#define RID2RSET(r) (((RegSet)1) << (r))
#define RSET_EMPTY ((RegSet)0)
#define RSET_RANGE(lo, hi) ((RID2RSET((hi)-(lo))-1) << (lo))
#define rset_test(rs, r) ((int)((rs) >> (r)) & 1)
#define rset_set(rs, r) (rs |= RID2RSET(r))
#define rset_clear(rs, r) (rs &= ~RID2RSET(r))
#define rset_exclude(rs, r) (rs & ~RID2RSET(r))
#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64
#define rset_picktop(rs) ((Reg)(__builtin_clzll(rs)^63))
#define rset_pickbot(rs) ((Reg)__builtin_ctzll(rs))
#else
#define rset_picktop(rs) ((Reg)lj_fls(rs))
#define rset_pickbot(rs) ((Reg)lj_ffs(rs))
#endif
/* -- Register allocation cost -------------------------------------------- */
/* The register allocation heuristic keeps track of the cost for allocating
** a specific register:
**
** A free register (obviously) has a cost of 0 and a 1-bit in the free mask.
**
** An already allocated register has the (non-zero) IR reference in the lowest
** bits and the result of a blended cost-model in the higher bits.
**
** The allocator first checks the free mask for a hit. Otherwise an (unrolled)
** linear search for the minimum cost is used. The search doesn't need to
** keep track of the position of the minimum, which makes it very fast.
** The lowest bits of the minimum cost show the desired IR reference whose
** register is the one to evict.
**
** Without the cost-model this degenerates to the standard heuristics for
** (reverse) linear-scan register allocation. Since code generation is done
** in reverse, a live interval extends from the last use to the first def.
** For an SSA IR the IR reference is the first (and only) def and thus
** trivially marks the end of the interval. The LSRA heuristics says to pick
** the register whose live interval has the furthest extent, i.e. the lowest
** IR reference in our case.
**
** A cost-model should take into account other factors, like spill-cost and
** restore- or rematerialization-cost, which depend on the kind of instruction.
** E.g. constants have zero spill costs, variant instructions have higher
** costs than invariants and PHIs should preferably never be spilled.
**
** Here's a first cut at simple, but effective blended cost-model for R-LSRA:
** - Due to careful design of the IR, constants already have lower IR
** references than invariants and invariants have lower IR references
** than variants.
** - The cost in the upper 16 bits is the sum of the IR reference and a
** weighted score. The score currently only takes into account whether
** the IRT_ISPHI bit is set in the instruction type.
** - The PHI weight is the minimum distance (in IR instructions) a PHI
** reference has to be further apart from a non-PHI reference to be spilled.
** - It should be a power of two (for speed) and must be between 2 and 32768.
** Good values for the PHI weight seem to be between 40 and 150.
** - Further study is required.
*/
#define REGCOST_PHI_WEIGHT 64
/* Cost for allocating a specific register. */
typedef uint32_t RegCost;
/* Note: assumes 16 bit IRRef1. */
#define REGCOST(cost, ref) ((RegCost)(ref) + ((RegCost)(cost) << 16))
#define regcost_ref(rc) ((IRRef1)(rc))
#define REGCOST_T(t) \
((RegCost)((t)&IRT_ISPHI) * (((RegCost)(REGCOST_PHI_WEIGHT)<<16)/IRT_ISPHI))
#define REGCOST_REF_T(ref, t) (REGCOST((ref), (ref)) + REGCOST_T((t)))
/* -- Target-specific definitions ----------------------------------------- */
#if LJ_TARGET_X86ORX64
#include "lj_target_x86.h"
#elif LJ_TARGET_ARM
#include "lj_target_arm.h"
#elif LJ_TARGET_ARM64
#include "lj_target_arm64.h"
#elif LJ_TARGET_PPC
#include "lj_target_ppc.h"
#elif LJ_TARGET_MIPS
#include "lj_target_mips.h"
#else
#error "Missing include for target CPU"
#endif
#ifdef EXITSTUBS_PER_GROUP
/* Return the address of an exit stub. */
static LJ_AINLINE char *exitstub_addr_(char **group, uint32_t exitno)
{
lua_assert(group[exitno / EXITSTUBS_PER_GROUP] != NULL);
return (char *)group[exitno / EXITSTUBS_PER_GROUP] +
EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP);
}
/* Avoid dependence on lj_jit.h if only including lj_target.h. */
#define exitstub_addr(J, exitno) \
((MCode *)exitstub_addr_((char **)((J)->exitstubgroup), (exitno)))
#endif
#endif

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