Compare commits

...

126 Commits

Author SHA1 Message Date
Martin Felis 962c894908 Release cleanup 2015-12-22 16:02:02 +01:00
Martin Felis 26a6c423f9 Updated to latest LÖVE code 2f5d329b07d7 (android: disable JIT by default as it may cause performance problems) 2015-12-22 10:06:57 +01:00
Martin Felis 08d51fbf28 Updated LÖVE source to changeset da332813bc05 2015-12-20 22:52:22 +01:00
Martin Felis eac5db7e10 Updated README.md for 0.10.0-alpha2 2015-12-09 23:52:09 +01:00
Martin Felis 28d2d92645 Updated LuaJIT to latest 2.1 version 2015-12-09 22:51:28 +01:00
Martin Felis 66685a2ade Updated LÖVE source to revision cff5bc8604bd 2015-12-09 22:19:41 +01:00
Martin Felis 8f5ee4a05e added building of the theora library 2015-12-09 12:41:20 +01:00
fysx 686e1d5f3e Update LÖVE to changeset 7cb21c8bdd64 (pre 0.10.0) 2015-12-01 23:07:34 +01:00
fysx 7e877716d6 Updated SDL2 to changeset 69a5f3a540af (dev version of 2.0.4) 2015-12-01 22:29:54 +01:00
fysx ec5f068b19 Updated OpenAL to version 1.16.0 2015-11-29 15:27:32 +01:00
fysx 8308a524bc Updated libogg to 1.3.2 and libvorbis to 1.3.5 2015-11-28 22:14:03 +01:00
fysx 4439a193d6 Fixed issue #115 (compatibility with Android 2.3 devices) 2015-11-28 21:58:50 +01:00
fysx 9cbddc2f5e Updated to latest love-android code (b615972822cb) 2015-08-13 17:21:53 +02:00
fysx f3dd769e98 Using latest love-android branch (9a508a54700d) 2015-08-13 11:12:17 +02:00
fysx c91dbb6957 Forcing use of GCC 4.8 to prevent compiling issues 2015-07-15 11:10:46 +02:00
fysx 198c2d28de new version: 0.10.0-alpha. Warning: this uses the not yet released 0.10.0 API of LÖVE. 0.9.2 games likely don't work! 2015-07-03 19:40:31 +02:00
fysx 357a7237a4 Using latest android branch of LÖVE (6d14516b05c9) that now syncs with default (woooo!) 2015-07-03 19:09:18 +02:00
fysx 1924bbdeeb updated changelog for 0.9.2a 2015-04-10 16:01:39 +02:00
fysx d783f5afa1 Preparing 0.9.2a release 2015-04-10 15:59:27 +02:00
fysx 7eb7db1a85 Imported latest love-android code 8e93b946d920 that fixes ParticleSystem:clone 2015-04-10 15:45:46 +02:00
fysx 8af8dffad4 fixed README markup 2015-04-10 11:55:14 +02:00
fysx a0efc89a7d preparing release 0.9.2 2015-04-10 11:43:31 +02:00
fysx c30e788393 properly detect whether we are in "fullscreen" (i.e. immersive) on Android 2015-02-19 00:15:31 +01:00
fysx 168357e1ad fixed #104: loading of multiple .love files 2015-02-18 10:33:54 +01:00
fysx d6f1d8bd70 imported changes from love-0.9.2 2015-02-16 00:37:14 +01:00
fysx 3cfecd46d9 added Download section to README.md 2015-02-15 23:21:53 +01:00
fysx f31760c445 made love.window.setFullscreen() work 2015-02-02 22:42:08 +01:00
fysx d0f866e4b0 fixed build for latest love-android version 2015-01-22 20:57:57 +01:00
fysx 542c029666 updated to latest love-android (changeset 7b5f223900b) 2015-01-22 10:48:45 +01:00
fysx 31cd05551e renamed setBorderless to setImmersive and linked it to the fullscreen mode 2015-01-20 22:11:56 +01:00
fysx 42f6beaa7e Allowing enabling and disabling of immersive mode via borderless setting and love.window.setMode() 2015-01-20 16:01:43 +01:00
fysx 36216c16be fixed immersive mode when resuming 2015-01-20 14:36:57 +01:00
fysx 013df025d0 fix for #91 and #98: printing of non-number and non-string values 2015-01-16 22:13:33 +01:00
fysx 535a8256ee Using immersive mode by default 2015-01-16 20:41:03 +01:00
fysx b732d6cc12 replaced tabs with spaces 2015-01-16 20:40:23 +01:00
fysx 54215b7ce4 refactored loading of games on android 2015-01-16 20:00:51 +01:00
fysx fd9e9758a9 Using latest changeset 593639000823 of love-android 2015-01-16 12:31:11 +01:00
fysx f46115e794 ignoring *.orig files from mercurial merges 2015-01-16 12:30:43 +01:00
fysx 29a3e4b566 fixed APP_PLATFORM warning 2015-01-13 20:57:00 +01:00
fysx 02dc18a587 fixed compilation with Android NDK r10 2015-01-11 22:23:12 +01:00
fysx a034220b10 tried to list dependent softwares and licenses 2014-11-12 10:37:43 +01:00
fysx 72b2fcd4eb Added loading of games by opening the main.lua file 2014-10-22 11:54:04 +02:00
fysx b20f7e7302 Stop the vibrator when the app is paused (e.g. when device is switched off or app goes in background) 2014-10-22 11:26:52 +02:00
fysx 6b1fae429b not calling exit(retval) when main ends 2014-10-21 12:21:02 +02:00
fysx 4ec2e26985 updated to latest SDL2 (f9244b2a151) 2014-10-21 12:20:26 +02:00
fysx 8df94d2a8a Properly pausing OpenAL device using the extension alcDevicePauseSOFT (fixes #83) 2014-09-09 10:29:56 +02:00
fysx 70eef137ae updated OpenAL-Soft to version 1.16.0 2014-09-08 21:17:12 +02:00
fysx 4f11bd0e7b fixed #82: was using wrong argument to query module instance 2014-08-31 14:14:15 +02:00
fysx 5048f3ff8c properly increased android:versionCode 2014-08-28 15:28:57 +02:00
fysx 66f600b5ab New version: 0.9.1b 2014-08-28 11:52:30 +02:00
fysx 659b312121 fixed mousepress event coordinates 2014-08-28 11:44:32 +02:00
fysx b875fffedb updated from latest love-android (228a26ab99bb) 2014-08-28 10:55:10 +02:00
fysx 45b1fc2509 fixed compilation and removed some unneeded files 2014-08-27 23:33:50 +02:00
fysx c6ac06c366 actual update to latest mobile-common 2014-08-27 23:23:26 +02:00
fysx abb819335b updated to latest mobile-common (0cf55b7da58e), removed libtiff, libpng, libmng, devil, jasper, jpeg-8d, added libturbo-jpeg 2014-08-27 23:19:11 +02:00
Martin Felis aba2f47b31 removed printing redirect tag from [LOVE2D] to [LOVE] 2014-08-18 19:04:40 +02:00
Martin Felis ea459a43da removed random text 2014-08-18 19:03:55 +02:00
Martin Felis 6110de0fa8 implemented love.system.vibrate(seconds) 2014-08-18 18:47:13 +02:00
Martin Felis 8f20cb7cc5 added print redirect to SDL_Log (fixes #40) 2014-08-18 16:23:39 +02:00
Martin Felis b25af54383 Merged in PabloMayobre/love-android-sdl2/PabloMayobre/same-as-4c481f993306-use-app_process-as-1405185954174 (pull request #3)
Same as  4c481f9933. Use 'app_process' as executable name (should fix #71 and #23)

Thanks!!
2014-07-12 21:47:41 +02:00
Pablo Mayobre c27f19c141 Same as 4c481f9933. Use 'app_process' as executable name (should fix #71 and #23) 2014-07-12 17:25:58 +00:00
fysx d1ad6cc5a3 fixed README markdown syntax 2014-07-01 17:08:55 +02:00
fysx afe33f06d2 Updated Readme for tag 0.9.1a 2014-07-01 17:06:27 +02:00
fysx 70cb26bb2a bumped version to 0.9.1a 2014-05-25 16:34:53 +02:00
fysx 8cb7bac09f using latest SDL_androidgl.c that removes some calls to eglWaitXXX() calls 2014-05-25 16:30:27 +02:00
fysx 49265f0596 using latest love-android @ changeset 8659be0e75a3 2014-05-25 16:27:34 +02:00
fysx 1d29da2d80 preparing release 0.9.1 2014-05-12 21:43:03 +02:00
fysx 6459889d32 fixed loading of jpegs by reverting libjpeg to version 8d 2014-05-12 00:08:20 +02:00
fysx 6be242ef03 newly generated graphics.lua.h (should actually fix #31) 2014-05-03 17:26:21 +02:00
fysx 97d9154e48 updated to latest mobile-common (should fix love.touch index problems) 2014-05-03 14:13:40 +02:00
fysx c40250e565 fix for #31 2014-05-03 14:06:28 +02:00
fysx 684adff826 updated manifest for 0.9.1-RC1 version 2014-04-04 13:24:10 +02:00
fysx ec9be8a383 removed duplicate entries in AndroidManifest.xml 2014-04-04 13:09:39 +02:00
fysx d637b5c11d updated SDLActivity.java 2014-04-04 13:06:32 +02:00
fysx adc4042d8b deleted stale file 2014-04-04 11:38:13 +02:00
fysx e96eef4435 Using latest love-android branch (e263d91d136d) 2014-04-04 11:37:36 +02:00
fysx 8acfb8d91a Disabled building of dynamic library for SDL2 2014-04-04 11:35:52 +02:00
fysx cc829bdd1e added code to support the upcoming love.system.openURL 2014-04-03 18:20:37 +02:00
fysx 7593d64761 Upgraded SDL2 to version 2.0.3 2014-04-03 16:45:01 +02:00
fysx f09239788a fixed markdown in README 2014-02-23 15:28:17 +01:00
fysx c0fd9a6e1b beta2 2014-02-23 15:21:29 +01:00
fysx 539ca8d4f2 fixed opening of .love files when URL is entered in Chrome 2014-02-23 14:51:33 +01:00
fysx fab725ad8b using identity 'unnamed' if none is specified in conf.lua(fixes issue #46) 2014-02-20 22:31:59 +01:00
fysx 5f6fa8c2b5 Proper downloading of games and starting works when downloaded using the LÖVE app 2014-02-20 21:27:34 +01:00
fysx 4c2846f4bb download and progress bar somewhat work 2014-02-19 20:57:09 +01:00
fysx cb2c852f58 trying to add running of games via http link 2014-02-14 01:41:47 +01:00
fysx 60a58f9240 Merged GameLauncher and GameActivity together
The GameActivity would not run otherwise as the App started via
GameActivity would call in love::android::getSelectedGameFile() the wrong
activity (namely GameLauncher) that was not initialized properly. Hence it
would result in a segfault.
2014-02-14 00:56:47 +01:00
fysx 5849e8d369 fixed indentations 2014-02-13 14:24:17 +01:00
fysx 1703660617 fixed loading of files from file managers 2014-02-13 14:08:06 +01:00
fysx 0db55463c9 Allow .love files to be opened from email attachements 2014-02-13 13:56:23 +01:00
fysx 288b25c585 ensure that static variable is properly initialized 2014-02-13 01:31:20 +01:00
fysx a5284dccf6 Merge branch 'filetype_association' 2014-02-13 01:30:36 +01:00
Jairo Luiz 8069dc02c6 Now, we have a filetype association!!!! :) 2014-02-12 20:56:11 -03:00
fysx 0bde453b2e updated to changeset 80f0adedfaa5 of love-android (including newest mobile-common changes) 2014-02-13 00:44:51 +01:00
fysx 667c4750ea properly load shared libraries 2014-02-11 02:00:33 +01:00
fysx 38727b5c25 beta1 - here we go 2014-02-11 01:03:39 +01:00
fysx 288a851a65 fix for the fix for the non-improvement 2014-02-11 00:42:05 +01:00
fysx 5e3579f680 should fix the crash on startup 2014-02-11 00:26:03 +01:00
fysx 1dd859c9d1 fixed indentations 2014-02-10 08:31:40 +01:00
fysx 53d45533e0 properly using workaround for love.filesystem.getDirectoryItems 2014-02-10 08:30:43 +01:00
fysx 3f13dc653f fixed issue tracker link 2014-02-09 23:57:03 +01:00
fysx 9e7e31ba05 preparing alpha9 release 2014-02-09 23:15:15 +01:00
fysx 3f268ebedf Added workaround for love.filesystem.getDirectoryItems 2014-02-09 23:02:04 +01:00
fysx 8fb02e11ab static linking of SDL2: do not load libSDL2.so from Java 2014-02-09 22:58:45 +01:00
fysx 89c54f9712 Using static linking for SDL2 2014-02-09 15:01:12 +01:00
fysx 606da6d0ae removed debug output 2014-02-08 00:41:45 +01:00
fysx 52d505624d further readme tweaks 2014-02-07 23:46:12 +01:00
fysx 89c9baf274 trying to link to the wiki from the readme file 2014-02-07 23:43:14 +01:00
fysx e4e1a0f59b properly use dynamic linking for LGPL libraries 2014-02-07 23:40:02 +01:00
fysx 00052d8067 Use SDL_AndroidGetActivity() instead of the full activity name (better for custom packages) 2014-02-06 01:29:36 +01:00
fysx de93ded9bf removed include dir for the SDL private headers 2014-02-06 01:18:17 +01:00
fysx 2da2da2652 Replaced use of SDL internal header file with the public interface 2014-02-06 01:13:38 +01:00
fysx bfae01300e fixed mouse coordinates due to the love.window.getScale() change 2014-02-06 01:02:47 +01:00
fysx 0b8dd90114 properly free JNI objects 2014-02-06 00:52:52 +01:00
fysx 3cabe641d6 Disable OpenGL debug on OpenGL ES2 (should fix Ouya compatibility) 2014-02-06 00:14:33 +01:00
fysx 351e224815 LuaJIT: use proper -mfpu flags and added new binaries 2014-02-06 00:07:56 +01:00
Martin Felis 89c2c014b2 Merged in josefnpat's fantastic icon. THANKS!!!
Updating `res/drawable-*/ic_launcher.png` to proposed icon (icon2)
2014-02-05 23:59:52 +01:00
Josef Patoprsty c3a21270ab Updating res/drawable-*/ic_launcher.png to proposed icon (icon2) 2014-02-05 13:12:04 -05:00
Martin Felis 597fad8034 Merged tangerinagames/love-android-sdl2/pixel_scale into master 2014-02-02 21:28:09 +01:00
fysx bf07caef09 Circumventing duplication of assets/game.love by mounting it from memory 2014-02-02 02:19:29 +01:00
fysx c9bb6ec3d6 updated physfs to inofficial 2.1 version 2014-02-02 01:28:41 +01:00
Jairo Luiz 007b0fc3f0 love.window.getPixelScale now works properly on Android. 2014-01-30 15:08:15 -03:00
Jairo Luiz b86319c0f4 remove OpenAL LOCAL_LDLIBS warning 2014-01-30 14:51:03 -03:00
Jairo Luiz 9a688b9b37 remove unnecessary “love.android” module 2014-01-30 14:43:12 -03:00
fysx 405c79a8fe adjusted changelog 2014-01-30 10:32:38 +01:00
fysx cf30c31234 fixed markdown 2014-01-30 10:30:25 +01:00
5472 changed files with 468238 additions and 1171446 deletions
+4
View File
@@ -12,6 +12,8 @@ local.properties
*.o
*.so
*.a
*.orig
*.rej
!jni/LuaJIT-2.0.1/android/armeabi/libluajit.a
!jni/LuaJIT-2.0.1/android/armeabi-v7a/libluajit.a
@@ -29,3 +31,5 @@ jni/LuaJIT-2.0.1/src/lj_libdef.h
jni/LuaJIT-2.0.1/src/lj_recdef.h
jni/LuaJIT-2.0.1/src/lj_vm.s
jni/LuaJIT-2.0.1/src/luajit
jni/love/src/Makefile.am
+54 -17
View File
@@ -1,29 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.love2d.android"
android:versionCode="8"
android:versionName="0.9.0-alpha8"
android:versionCode="19"
android:versionName="0.10.0"
android:installLocation="auto" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="Löve for Android"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name="GameActivity"
android:configChanges="orientation|screenSize"
android:label="Löve for Android"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="tv.ouya.intent.category.GAME"/>
</intent-filter>
</activity>
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="LÖVE for Android"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<service android:name=".DownloadService" />
<activity
android:name="GameActivity"
android:configChanges="orientation|screenSize"
android:label="LÖVE for Android"
android:launchMode="singleTop"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="tv.ouya.intent.category.GAME"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="application/x-love-game" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.love" />
<data android:host="*" />
</intent-filter>
</activity>
<activity
android:name="DownloadActivity"
android:noHistory="true" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"
android:host="*"
android:pathPrefix="*"
android:mimeType="*/*"
android:pathPattern=".*\\.love" />
<data android:scheme="https"
android:host="*"
android:pathPrefix="*"
android:mimeType="*/*"
android:pathPattern=".*\\.love" />
</intent-filter>
</activity>
</application>
<!-- Android 2.3.3 -->
+135 -13
View File
@@ -1,12 +1,27 @@
Android Port of LÖVE, the awesome 2D game engine LÖVE (http://love2d.org)
Copyright (c) 2013 Martin Felis <martin@fysx.org>
Copyright (c) 2013-2014 Martin Felis <martin@fysx.org>
Instructions:
-------------
Install the Android NDK and the Android SDK with SDK API 12 and run
For detailed instructions please refer to the wiki at [https://bitbucket.org/MartinFelis/love-android-sdl2/wiki/Home](https://bitbucket.org/MartinFelis/love-android-sdl2/wiki/Home).
ndk-build
Download:
---------
You can download pre-built Android packages from
[https://bitbucket.org/MartinFelis/love-android-sdl2/downloads](https://bitbucket.org/MartinFelis/love-android-sdl2/downloads)
that allow you to run .love files by opening them using a file manager of
your choice.
Quick Start:
------------
Install the Android NDK and the Android SDK with SDK API 23, set the
environment variables ```ANDROID_NDK```, ```ANDROID_SDK```, and
```ANDROID_HOME``` and run
ndk-build -j4
and after that
@@ -18,14 +33,93 @@ compile/run it using Eclipse.
This should give you a .apk file in the bin/ subdirectory that you can then
install on your phone.
Bugs:
-----
Bugs and feature requests should be reported to the issue tracker at [https://bitbucket.org/MartinFelis/love-android-sdl2/issues?status=new&status=open](https://bitbucket.org/MartinFelis/love-android-sdl2/issues?status=new&status=open).
Changelog:
----------
0.10.0:
* first official release!
* Disabled JIT by default as it can cause performance problems. To enable JIT call jit.on()
0.10.0-alpha2:
* Update to the next love API 0.10.0 (not yet officially released)
* Added building of libtheora
* Updated LuaJIT from 2.0.1 to 2.1
* Fixed a compatibility issue with Android 2.3 devices
* Updated libogg from 1.3.2. to 1.3.5
* Updated OpenAL to 1.17.0
* Updated SDL2 to a dev version of 2.0.4
0.9.2a:
* Added bugfix for ParticleSystem:clone
0.9.2:
* updated API to match that of LÖVE 0.9.2
* love.window.setFullscreen can be used to switch between regular and immersive mode without status and navbar
* added loading of games by opening a main.lua file
* quitting LÖVE now conforms to the Android application lifecycle
* stop vibrator when app is paused
* fixed battery drain by properly pausing OpenAL device
* fixed printing of non-number and non-string values
* fixed compilation of Android NDK r10
* fixed compilation warnings concerning ```APP_PLATFORM```
* old instance is shut down when opening a new game (note: it may crash when opening games at a high frequency, e.g. more than 2 per second)
* updated OpenAL-Soft to version 1.16.0
* updated to newer SDL version (f9244b2a151)
0.9.1b:
* added love.system.vibrate(seconds)
* print statements are now redirected to logcat. Output is prefixed with "[LOVE] "
* removed DevIL, libpng, libjpeg, libmng, and libtiff
* pngs are loaded using lodepng and jpegs using libturbo-jpeg
* repeatedly fixed a bug which caused Release builds to crash
* update to latest mobile-common branch
0.9.1a:
* using latest SDL\_androidgl.c (fixes some random performance issues)
* using latest love-android @ changeset 8659be0e75a3 (adds support for
compressed textures)
0.9.1:
* uses 0.9.1 API
* fixed crash on Moto G (and possibly other devices). This was a nasty bug that would just show a blue screen without an error message. The bug was resolved using the help of headchant
* fixed loading of jpegs (it probably hasn't worked up to now)
* fixed issues with looping over active touches. This fix was sponsored by slime!
beta2:
* fixed bug with canvases
* fixed writing of files when no identity in conf.lua was set
* added file association (somewhat experimental)
beta1:
* fixed nasty crash on startup bug
* fixed love.filesystem.getDirectoryItems()
alpha9:
* Packaged games do not get duplicated for loading, instead are loaded from memory (!!!)
* Using inofficial physfs 2.1
* Removed love.android.getDisplayMetrics(), instead use love.window.getPixelScale()
* Properly link LGPL libraries dynamically. Everything else is linked statically
* Added an icon (design by @josefnpat)
* Fixed crash on startup on OUYA (and possibly other devices)
alpha8:
* Exposing DisplayMetrics in love.android.getDisplayMetrics())
* Accelerometer is now available as a joystick
* enabled armv6 compilation (larger files, better compatibility with Tegra2 devices)
* updated to latest mobile-common branch
* updated to latest mobile-common branch (including (very) basic multi-touch gesture tracking)
* updated OpenAL from 1.13 to 1.15.1
* updated jpeg library from 8c to 9a
* updated lcms from 2.2 to 2.5
@@ -34,18 +128,46 @@ alpha8:
* updated mpg123 from 1.13.4 to 1.17.0
alpha7:
* love.system.getOS() now returns "Android"
* hardware search key is reported as "search"
* switched to mobile-common branch
* using new love.touch module (love.touchpressed(id,x,y,p), love.touchmoved(id,x,y,p), love.touchmoved(id,x,y,p))
* added LOVE_ANDROID define
* love.system.getOS() now returns "Android"
* hardware search key is reported as "search"
* switched to mobile-common branch
* using new love.touch module (love.touchpressed(id,x,y,p), love.touchmoved(id,x,y,p), love.touchmoved(id,x,y,p))
* added LOVE_ANDROID define
License:
--------
This project contains code from various projects using various licenses.
This project contains code from multiple projects using various licenses.
Please look into the folders of jni/<projectname>/ for the respective
licenses.
licenses. A possibly incomplete overview of dependent and included
libraries and licenses is the following:
As for the other code and build system files, these are published under the
zlib license (same as LÖVE).
* FreeType2 (FreeType Project License)
* libjpeg-turbo (custom license)
* libmodplug (public domain)
* libogg (BSD License)
* libvorbis (BSD License)
* LuaJIT (MIT License)
* mpg123 (LGPL 2.1 License)
* openal-soft (LGPL 2 License)
* physfs (zlib License)
* SDL2 (zlib License)
This project also includes LÖVE, which itself is licensed under the zlib
license but includes the following libraries that are subject to other
licenses:
* modified Box2D (original Box2D license is zlib)
* ddsparse (MIT License)
* enet (MIT License)
* glad (MIT License)
* lodepng (zlib License)
* luasocket (MIT License)
* SimplexNoise1234 (public domain)
* stb_image (public domain)
* utf8 (Boost License)
* wuff (public domain)
As for the other code, modifications to LÖVE, and build system files are
are published under the zlib license (same as LÖVE).
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This should be changed to the name of your project -->
<project name="love_android_sdl2" default="help">
<project name="love-android" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
+3 -1
View File
@@ -4,6 +4,8 @@
APP_STL := gnustl_shared
APP_ABI := armeabi armeabi-v7a
APP_CPPFLAGS := -frtti
APP_LDFLAGS := -llog -landroid -lz -lOpenSLES
APP_LDFLAGS := -llog -landroid -lz
APP_PLATFORM := 10
NDK_TOOLCHAIN_VERSION := 4.8
# APP_OPTIM := debug
-56
View File
@@ -1,56 +0,0 @@
===============================================================================
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
Copyright (C) 2005-2013 Mike Pall. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
===============================================================================
[ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
Copyright (C) 1994-2012 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
[ LuaJIT includes code from dlmalloc, which has this license statement: ]
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
http://creativecommons.org/licenses/publicdomain
===============================================================================
-149
View File
@@ -1,149 +0,0 @@
##############################################################################
# LuaJIT top level Makefile for installation. Requires GNU Make.
#
# Please read doc/install.html before changing any variables!
#
# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
# Note: src/Makefile has many more configurable options.
#
# ##### This Makefile is NOT useful for Windows! #####
# For MSVC, please follow the instructions given in src/msvcbuild.bat.
# For MinGW and Cygwin, cd to src and run make with the Makefile there.
#
# Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
##############################################################################
MAJVER= 2
MINVER= 0
RELVER= 1
VERSION= $(MAJVER).$(MINVER).$(RELVER)
ABIVER= 5.1
##############################################################################
#
# Change the installation path as needed. This automatically adjusts
# the paths in src/luaconf.h, too. Note: PREFIX must be an absolute path!
#
export PREFIX= /usr/local
##############################################################################
DPREFIX= $(DESTDIR)$(PREFIX)
INSTALL_BIN= $(DPREFIX)/bin
INSTALL_LIB= $(DPREFIX)/lib
INSTALL_SHARE= $(DPREFIX)/share
INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(VERSION)
INSTALL_JITLIB= $(INSTALL_LJLIBD)/jit
INSTALL_LMODD= $(INSTALL_SHARE)/lua
INSTALL_LMOD= $(INSTALL_LMODD)/$(ABIVER)
INSTALL_CMODD= $(INSTALL_LIB)/lua
INSTALL_CMOD= $(INSTALL_CMODD)/$(ABIVER)
INSTALL_MAN= $(INSTALL_SHARE)/man/man1
INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig
INSTALL_TNAME= luajit-$(VERSION)
INSTALL_TSYMNAME= luajit
INSTALL_ANAME= libluajit-$(ABIVER).a
INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER)
INSTALL_SOSHORT= libluajit-$(ABIVER).so
INSTALL_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
INSTALL_DYLIBSHORT1= libluajit-$(ABIVER).dylib
INSTALL_DYLIBSHORT2= libluajit-$(ABIVER).$(MAJVER).dylib
INSTALL_PCNAME= luajit.pc
INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME)
INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME)
INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME)
INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME)
INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
$(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
UNINSTALL_DIRS= $(INSTALL_JITLIB) $(INSTALL_LJLIBD) $(INSTALL_INC) \
$(INSTALL_LMOD) $(INSTALL_LMODD) $(INSTALL_CMOD) $(INSTALL_CMODD)
RM= rm -f
MKDIR= mkdir -p
RMDIR= rmdir 2>/dev/null
SYMLINK= ln -sf
INSTALL_X= install -m 0755
INSTALL_F= install -m 0644
UNINSTALL= $(RM)
LDCONFIG= ldconfig -n
SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|"
FILE_T= luajit
FILE_A= libluajit.a
FILE_SO= libluajit.so
FILE_MAN= luajit.1
FILE_PC= luajit.pc
FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua dis_arm.lua \
dis_ppc.lua dis_mips.lua dis_mipsel.lua bcsave.lua vmdef.lua
ifeq (,$(findstring Windows,$(OS)))
ifeq (Darwin,$(shell uname -s))
INSTALL_SONAME= $(INSTALL_DYLIBNAME)
INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT1)
INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT2)
LDCONFIG= :
endif
endif
##############################################################################
INSTALL_DEP= src/luajit
default all $(INSTALL_DEP):
@echo "==== Building LuaJIT $(VERSION) ===="
$(MAKE) -C src
@echo "==== Successfully built LuaJIT $(VERSION) ===="
install: $(INSTALL_DEP)
@echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ===="
$(MKDIR) $(INSTALL_DIRS)
cd src && $(INSTALL_X) $(FILE_T) $(INSTALL_T)
cd src && test -f $(FILE_A) && $(INSTALL_F) $(FILE_A) $(INSTALL_STATIC) || :
$(RM) $(INSTALL_TSYM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
cd src && test -f $(FILE_SO) && \
$(INSTALL_X) $(FILE_SO) $(INSTALL_DYN) && \
$(LDCONFIG) $(INSTALL_LIB) && \
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \
$(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \
$(RM) $(FILE_PC).tmp
cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC)
cd src/jit && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
$(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)
@echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ===="
uninstall:
@echo "==== Uninstalling LuaJIT $(VERSION) from $(PREFIX) ===="
$(UNINSTALL) $(INSTALL_TSYM) $(INSTALL_T) $(INSTALL_STATIC) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2) $(INSTALL_MAN)/$(FILE_MAN) $(INSTALL_PC)
for file in $(FILES_JITLIB); do \
$(UNINSTALL) $(INSTALL_JITLIB)/$$file; \
done
for file in $(FILES_INC); do \
$(UNINSTALL) $(INSTALL_INC)/$$file; \
done
$(LDCONFIG) $(INSTALL_LIB)
$(RMDIR) $(UNINSTALL_DIRS) || :
@echo "==== Successfully uninstalled LuaJIT $(VERSION) from $(PREFIX) ===="
##############################################################################
amalg:
@echo "Building LuaJIT $(VERSION)"
$(MAKE) -C src amalg
clean:
$(MAKE) -C src clean
.PHONY: all install amalg clean
##############################################################################
-16
View File
@@ -1,16 +0,0 @@
README for LuaJIT 2.0.1
-----------------------
LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
Project Homepage: http://luajit.org/
LuaJIT is Copyright (C) 2005-2013 Mike Pall.
LuaJIT is free software, released under the MIT license.
See full Copyright Notice in the COPYRIGHT file or in luajit.h.
Documentation for LuaJIT is available in HTML format.
Please point your favorite browser to:
doc/luajit.html
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
-24
View File
@@ -1,24 +0,0 @@
# Package information for LuaJIT to be used by pkg-config.
majver=2
minver=0
relver=1
version=${majver}.${minver}.${relver}
abiver=5.1
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
libname=luajit-${abiver}
includedir=${prefix}/include/luajit-${majver}.${minver}
INSTALL_LMOD=${prefix}/share/lua/${abiver}
INSTALL_CMOD=${prefix}/lib/lua/${abiver}
Name: LuaJIT
Description: Just-in-time compiler for Lua
URL: http://luajit.org
Version: ${version}
Requires:
Libs: -L${libdir} -l${libname}
Libs.private: -Wl,-E -lm -ldl
Cflags: -I${includedir}
-676
View File
@@ -1,676 +0,0 @@
##############################################################################
# LuaJIT Makefile. Requires GNU Make.
#
# Please read doc/install.html before changing any variables!
#
# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
# Also works with MinGW and Cygwin on Windows.
# Please check msvcbuild.bat for building with MSVC on Windows.
#
# Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
##############################################################################
MAJVER= 2
MINVER= 0
RELVER= 0
ABIVER= 5.1
NODOTABIVER= 51
##############################################################################
############################# COMPILER OPTIONS #############################
##############################################################################
# These options mainly affect the speed of the JIT compiler itself, not the
# speed of the JIT-compiled code. Turn any of the optional settings on by
# removing the '#' in front of them. Make sure you force a full recompile
# with "make clean", followed by "make" if you change any options.
#
# LuaJIT builds as a native 32 or 64 bit binary by default.
CC= gcc
#
# Use this if you want to force a 32 bit build on a 64 bit multilib OS.
#CC= gcc -m32
#
# Since the assembler part does NOT maintain a frame pointer, it's pointless
# to slow down the C part by not omitting it. Debugging, tracebacks and
# unwinding are not affected -- the assembler part has frame unwind
# information and GCC emits it where needed (x64) or with -g (see CCDEBUG).
CCOPT= -O2 -fomit-frame-pointer
# Use this if you want to generate a smaller binary (but it's slower):
#CCOPT= -Os -fomit-frame-pointer
# Note: it's no longer recommended to use -O3 with GCC 4.x.
# The I-Cache bloat usually outweighs the benefits from aggressive inlining.
#
# Target-specific compiler options:
#
# x86 only: it's recommended to compile at least for i686. Better yet,
# compile for an architecture that has SSE2, too (-msse -msse2).
#
# x86/x64 only: For GCC 4.2 or higher and if you don't intend to distribute
# the binaries to a different machine you could also use: -march=native
#
CCOPT_x86= -march=i686
CCOPT_x64=
CCOPT_arm=
CCOPT_ppc=
CCOPT_ppcspe=
CCOPT_mips=
#
CCDEBUG=
# Uncomment the next line to generate debug information:
#CCDEBUG= -g
#
CCWARN= -Wall
# Uncomment the next line to enable more warnings:
#CCWARN+= -Wextra -Wdeclaration-after-statement -Wredundant-decls -Wshadow -Wpointer-arith
#
##############################################################################
##############################################################################
################################ BUILD MODE ################################
##############################################################################
# The default build mode is mixed mode on POSIX. On Windows this is the same
# as dynamic mode.
#
# Mixed mode creates a static + dynamic library and a statically linked luajit.
BUILDMODE= mixed
#
# Static mode creates a static library and a statically linked luajit.
#BUILDMODE= static
#
# Dynamic mode creates a dynamic library and a dynamically linked luajit.
# Note: this executable will only run when the library is installed!
#BUILDMODE= dynamic
#
##############################################################################
##############################################################################
################################# FEATURES #################################
##############################################################################
# Enable/disable these features as needed, but make sure you force a full
# recompile with "make clean", followed by "make".
XCFLAGS=
#
# Permanently disable the FFI extension to reduce the size of the LuaJIT
# executable. But please consider that the FFI library is compiled-in,
# but NOT loaded by default. It only allocates any memory, if you actually
# make use of it.
#XCFLAGS+= -DLUAJIT_DISABLE_FFI
#
# Features from Lua 5.2 that are unlikely to break existing code are
# enabled by default. Some other features that *might* break some existing
# code (e.g. __pairs or os.execute() return values) can be enabled here.
# Note: this does not provide full compatibility with Lua 5.2 at this time.
#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
#
# Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter.
#XCFLAGS+= -DLUAJIT_DISABLE_JIT
#
# Some architectures (e.g. PPC) can use either single-number (1) or
# dual-number (2) mode. Uncomment one of these lines to override the
# default mode. Please see LJ_ARCH_NUMMODE in lj_arch.h for details.
#XCFLAGS+= -DLUAJIT_NUMMODE=1
#XCFLAGS+= -DLUAJIT_NUMMODE=2
#
##############################################################################
##############################################################################
############################ DEBUGGING SUPPORT #############################
##############################################################################
# Enable these options as needed, but make sure you force a full recompile
# with "make clean", followed by "make".
# Note that most of these are NOT suitable for benchmarking or release mode!
#
# Use the system provided memory allocator (realloc) instead of the
# bundled memory allocator. This is slower, but sometimes helpful for
# debugging. It's helpful for Valgrind's memcheck tool, too. This option
# cannot be enabled on x64, since the built-in allocator is mandatory.
#XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
#
# This define is required to run LuaJIT under Valgrind. The Valgrind
# header files must be installed. You should enable debug information, too.
# Use --suppressions=lj.supp to avoid some false positives.
#XCFLAGS+= -DLUAJIT_USE_VALGRIND
#
# This is the client for the GDB JIT API. GDB 7.0 or higher is required
# to make use of it. See lj_gdbjit.c for details. Enabling this causes
# a non-negligible overhead, even when not running under GDB.
#XCFLAGS+= -DLUAJIT_USE_GDBJIT
#
# Turn on assertions for the Lua/C API to debug problems with lua_* calls.
# This is rather slow -- use only while developing C libraries/embeddings.
#XCFLAGS+= -DLUA_USE_APICHECK
#
# Turn on assertions for the whole LuaJIT VM. This significantly slows down
# everything. Use only if you suspect a problem with LuaJIT itself.
#XCFLAGS+= -DLUA_USE_ASSERT
#
##############################################################################
# You probably don't need to change anything below this line!
##############################################################################
##############################################################################
# Flags and options for host and target.
##############################################################################
# You can override the following variables at the make command line:
# CC HOST_CC STATIC_CC DYNAMIC_CC
# CFLAGS HOST_CFLAGS TARGET_CFLAGS
# LDFLAGS HOST_LDFLAGS TARGET_LDFLAGS TARGET_SHLDFLAGS
# LIBS HOST_LIBS TARGET_LIBS
# CROSS HOST_SYS TARGET_SYS TARGET_FLAGS
#
# Cross-compilation examples:
# make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
# make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS)
LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
HOST_CC= $(CC)
HOST_RM= rm -f
# If left blank, minilua is built and used. You can supply an installed
# copy of (plain) Lua 5.1 or 5.2, plus Lua BitOp. E.g. with: HOST_LUA=lua
HOST_LUA=
HOST_XCFLAGS= -I.
HOST_XLDFLAGS=
HOST_XLIBS=
HOST_ACFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) $(HOST_CFLAGS)
HOST_ALDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) $(HOST_LDFLAGS)
HOST_ALIBS= $(HOST_XLIBS) $(LIBS) $(HOST_LIBS)
STATIC_CC = $(CROSS)$(CC)
DYNAMIC_CC = $(CROSS)$(CC) -fPIC
TARGET_CC= $(STATIC_CC)
TARGET_STCC= $(STATIC_CC)
TARGET_DYNCC= $(DYNAMIC_CC)
TARGET_LD= $(CROSS)$(CC)
TARGET_AR= $(CROSS)ar rcus
TARGET_STRIP= $(CROSS)strip
TARGET_SONAME= libluajit.so
TARGET_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).dylib
TARGET_DYLIBPATH= $(or $(PREFIX),/usr/local)/lib/$(TARGET_DYLIBNAME)
TARGET_DLLNAME= lua$(NODOTABIVER).dll
TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
TARGET_DYNXLDOPTS=
TARGET_LFSFLAGS= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
TARGET_XCFLAGS= $(TARGET_LFSFLAGS) -U_FORTIFY_SOURCE
TARGET_XLDFLAGS=
TARGET_XLIBS= -lm
TARGET_TCFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
TARGET_ACFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
TARGET_ALDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_FLAGS) $(TARGET_LDFLAGS)
TARGET_ASHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS) $(TARGET_FLAGS) $(TARGET_SHLDFLAGS)
TARGET_ALIBS= $(TARGET_XLIBS) $(LIBS) $(TARGET_LIBS)
TARGET_TESTARCH=$(shell $(TARGET_CC) $(TARGET_TCFLAGS) -E lj_arch.h -dM)
ifneq (,$(findstring LJ_TARGET_X64 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= x64
else
ifneq (,$(findstring LJ_TARGET_X86 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= x86
else
ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH)))
TARGET_LJARCH= arm
else
ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
TARGET_LJARCH= ppc
else
ifneq (,$(findstring LJ_TARGET_PPCSPE ,$(TARGET_TESTARCH)))
TARGET_LJARCH= ppcspe
else
ifneq (,$(findstring LJ_TARGET_MIPS ,$(TARGET_TESTARCH)))
ifneq (,$(findstring MIPSEL ,$(TARGET_TESTARCH)))
TARGET_ARCH= -D__MIPSEL__=1
endif
TARGET_LJARCH= mips
else
$(error Unsupported target architecture)
endif
endif
endif
endif
endif
endif
ifneq (,$(findstring LJ_TARGET_PS3 1,$(TARGET_TESTARCH)))
TARGET_SYS= PS3
TARGET_ARCH+= -D__CELLOS_LV2__
TARGET_XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
endif
ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
endif
TARGET_XCFLAGS+= $(CCOPT_$(TARGET_LJARCH))
TARGET_ARCH+= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET_LJARCH))
ifneq (,$(PREFIX))
ifneq (/usr/local,$(PREFIX))
TARGET_XCFLAGS+= -DLUA_XROOT=\"$(PREFIX)/\"
ifneq (/usr,$(PREFIX))
TARGET_DYNXLDOPTS= -Wl,-rpath,$(PREFIX)/lib
endif
endif
endif
##############################################################################
# System detection.
##############################################################################
ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM))
HOST_SYS= Windows
HOST_RM= del
else
HOST_SYS:= $(shell uname -s)
ifneq (,$(findstring MINGW,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= mingw
endif
ifneq (,$(findstring CYGWIN,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= cygwin
endif
endif
TARGET_SYS?= $(HOST_SYS)
ifeq (Windows,$(TARGET_SYS))
TARGET_STRIP+= --strip-unneeded
TARGET_XSHLDFLAGS= -shared
TARGET_DYNXLDOPTS=
else
ifeq (Darwin,$(TARGET_SYS))
ifeq (,$(MACOSX_DEPLOYMENT_TARGET))
export MACOSX_DEPLOYMENT_TARGET=10.4
endif
TARGET_STRIP+= -x
TARGET_AR+= 2>/dev/null
TARGET_XCFLAGS+= -fno-stack-protector
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
TARGET_DYNXLDOPTS=
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
ifeq (x64,$(TARGET_LJARCH))
TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000
TARGET_XSHLDFLAGS+= -image_base 7fff04c4a000
endif
else
ifeq (iOS,$(TARGET_SYS))
TARGET_STRIP+= -x
TARGET_AR+= 2>/dev/null
TARGET_XCFLAGS+= -fno-stack-protector
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
TARGET_DYNXLDOPTS=
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
else
ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs)))
TARGET_XCFLAGS+= -fno-stack-protector
endif
ifneq (SunOS,$(TARGET_SYS))
ifneq (PS3,$(TARGET_SYS))
TARGET_XLDFLAGS+= -Wl,-E
endif
endif
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
ifeq (GNU/kFreeBSD,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
endif
endif
endif
ifneq ($(HOST_SYS),$(TARGET_SYS))
ifeq (Windows,$(TARGET_SYS))
HOST_XCFLAGS+= -malign-double -DLUAJIT_OS=LUAJIT_OS_WINDOWS
else
ifeq (Linux,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_LINUX
else
ifeq (Darwin,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
else
ifeq (iOS,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
else
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
endif
endif
endif
endif
endif
ifneq (,$(CCDEBUG))
TARGET_STRIP= @:
endif
##############################################################################
# Files and pathnames.
##############################################################################
MINILUA_O= host/minilua.o
MINILUA_LIBS= -lm
MINILUA_T= host/minilua
MINILUA_X= $(MINILUA_T)
ifeq (,$(HOST_LUA))
HOST_LUA= $(MINILUA_X)
DASM_DEP= $(MINILUA_T)
endif
DASM_DIR= ../dynasm
DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
DASM_XFLAGS=
DASM_AFLAGS=
DASM_ARCH= $(TARGET_LJARCH)
ifneq (,$(findstring LJ_ARCH_BITS 64,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D P64
endif
ifneq (,$(findstring LJ_HASJIT 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D JIT
endif
ifneq (,$(findstring LJ_HASFFI 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FFI
endif
ifneq (,$(findstring LJ_DUALNUM 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D DUALNUM
endif
ifneq (,$(findstring LJ_ARCH_HASFPU 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FPU
TARGET_ARCH+= -DLJ_ARCH_HASFPU=1
else
TARGET_ARCH+= -DLJ_ARCH_HASFPU=0
endif
ifeq (,$(findstring LJ_ABI_SOFTFP 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D HFABI
TARGET_ARCH+= -DLJ_ABI_SOFTFP=0
else
TARGET_ARCH+= -DLJ_ABI_SOFTFP=1
endif
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
ifeq (Windows,$(TARGET_SYS))
DASM_AFLAGS+= -D WIN
endif
ifeq (x86,$(TARGET_LJARCH))
ifneq (,$(findstring __SSE2__ 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D SSE
endif
else
ifeq (x64,$(TARGET_LJARCH))
DASM_ARCH= x86
else
ifeq (arm,$(TARGET_LJARCH))
ifeq (iOS,$(TARGET_SYS))
DASM_AFLAGS+= -D IOS
endif
else
ifeq (ppc,$(TARGET_LJARCH))
ifneq (,$(findstring LJ_ARCH_SQRT 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D SQRT
endif
ifneq (,$(findstring LJ_ARCH_ROUND 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D ROUND
endif
ifneq (,$(findstring LJ_ARCH_PPC64 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D GPR64
endif
ifeq (PS3,$(TARGET_SYS))
DASM_AFLAGS+= -D PPE -D TOC
endif
endif
endif
endif
endif
DASM_FLAGS= $(DASM_XFLAGS) $(DASM_AFLAGS)
DASM_DASC= vm_$(DASM_ARCH).dasc
BUILDVM_O= host/buildvm.o host/buildvm_asm.o host/buildvm_peobj.o \
host/buildvm_lib.o host/buildvm_fold.o
BUILDVM_T= host/buildvm
BUILDVM_X= $(BUILDVM_T)
HOST_O= $(MINILUA_O) $(BUILDVM_O)
HOST_T= $(MINILUA_T) $(BUILDVM_T)
LJVM_S= lj_vm.s
LJVM_O= lj_vm.o
LJVM_BOUT= $(LJVM_S)
LJVM_MODE= elfasm
LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o
LJLIB_C= $(LJLIB_O:.o=.c)
LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \
lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_strscan.o \
lj_api.o lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \
lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \
lj_asm.o lj_trace.o lj_gdbjit.o \
lj_ctype.o lj_cdata.o lj_cconv.o lj_ccall.o lj_ccallback.o \
lj_carith.o lj_clib.o lj_cparse.o \
lj_lib.o lj_alloc.o lib_aux.o \
$(LJLIB_O) lib_init.o
LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
LIB_VMDEF= jit/vmdef.lua
LIB_VMDEFP= $(LIB_VMDEF)
LUAJIT_O= luajit.o
LUAJIT_A= libluajit.a
LUAJIT_SO= libluajit.so
LUAJIT_T= luajit
ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(HOST_T)
ALL_HDRGEN= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h \
host/buildvm_arch.h
ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP)
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
ALL_RM= $(ALL_T) $(ALL_GEN) *.o host/*.o $(WIN_RM)
##############################################################################
# Build mode handling.
##############################################################################
# Mixed mode defaults.
TARGET_O= $(LUAJIT_A)
TARGET_T= $(LUAJIT_T) $(LUAJIT_SO)
TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO)
ifeq (Windows,$(TARGET_SYS))
TARGET_DYNCC= $(STATIC_CC)
LJVM_MODE= coffasm
LUAJIT_T= luajit.exe
ifeq (cygwin,$(HOST_MSYS))
LUAJIT_SO= cyg$(TARGET_DLLNAME)
else
LUAJIT_SO= $(TARGET_DLLNAME)
endif
# Mixed mode is not supported on Windows. And static mode doesn't work well.
# C modules cannot be loaded, because they bind to lua51.dll.
ifneq (static,$(BUILDMODE))
BUILDMODE= dynamic
TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
endif
endif
ifeq (Darwin,$(TARGET_SYS))
LJVM_MODE= machasm
endif
ifeq (iOS,$(TARGET_SYS))
LJVM_MODE= machasm
endif
ifeq (SunOS,$(TARGET_SYS))
BUILDMODE= static
endif
ifeq (PS3,$(TARGET_SYS))
BUILDMODE= static
endif
ifeq (Windows,$(HOST_SYS))
MINILUA_T= host/minilua.exe
BUILDVM_T= host/buildvm.exe
ifeq (,$(HOST_MSYS))
MINILUA_X= host\minilua
BUILDVM_X= host\buildvm
ALL_RM:= $(subst /,\,$(ALL_RM))
endif
endif
ifeq (static,$(BUILDMODE))
TARGET_DYNCC= @:
TARGET_T= $(LUAJIT_T)
TARGET_DEP= $(LIB_VMDEF)
else
ifeq (dynamic,$(BUILDMODE))
ifneq (Windows,$(TARGET_SYS))
TARGET_CC= $(DYNAMIC_CC)
endif
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
TARGET_O= $(LUAJIT_SO)
TARGET_XLDFLAGS+= $(TARGET_DYNXLDOPTS)
else
ifeq (Darwin,$(TARGET_SYS))
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
endif
ifeq (iOS,$(TARGET_SYS))
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
endif
endif
endif
Q= @
E= @echo
#Q=
#E= @:
##############################################################################
# Make targets.
##############################################################################
default all: $(TARGET_T)
amalg:
@grep "^[+|]" ljamalg.c
$(MAKE) all "LJCORE_O=ljamalg.o"
clean:
$(HOST_RM) $(ALL_RM)
depend:
@for file in $(ALL_HDRGEN); do \
test -f $$file || touch $$file; \
done
@$(HOST_CC) $(HOST_ACFLAGS) -MM *.c host/*.c | \
sed -e "s| [^ ]*/dasm_\S*\.h||g" \
-e "s|^\([^l ]\)|host/\1|" \
-e "s| lj_target_\S*\.h| lj_target_*.h|g" \
-e "s| lj_emit_\S*\.h| lj_emit_*.h|g" \
-e "s| lj_asm_\S*\.h| lj_asm_*.h|g" >Makefile.dep
@for file in $(ALL_HDRGEN); do \
test -s $$file || $(HOST_RM) $$file; \
done
.PHONY: default all amalg clean depend
##############################################################################
# Rules for generated files.
##############################################################################
$(MINILUA_T): $(MINILUA_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(MINILUA_O) $(MINILUA_LIBS) $(HOST_ALIBS)
host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP)
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC)
host/buildvm.o: $(DASM_DIR)/dasm_*.h
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(BUILDVM_O) $(HOST_ALIBS)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
lj_bcdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m bcdef -o $@ $(LJLIB_C)
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
##############################################################################
# Object file rules.
##############################################################################
%.o: %.c
$(E) "CC $@"
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
%.o: %.s
$(E) "ASM $@"
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
$(LUAJIT_O):
$(E) "CC $@"
$(Q)$(TARGET_STCC) $(TARGET_ACFLAGS) -c -o $@ $<
$(HOST_O): %.o: %.c
$(E) "HOSTCC $@"
$(Q)$(HOST_CC) $(HOST_ACFLAGS) -c -o $@ $<
include Makefile.dep
##############################################################################
# Target file rules.
##############################################################################
$(LUAJIT_A): $(LJVMCORE_O)
$(E) "AR $@"
$(Q)$(TARGET_AR) $@ $(LJVMCORE_O)
# The dependency on _O, but linking with _DYNO is intentional.
$(LUAJIT_SO): $(LJVMCORE_O)
$(E) "DYNLINK $@"
$(Q)$(TARGET_LD) $(TARGET_ASHLDFLAGS) -o $@ $(LJVMCORE_DYNO) $(TARGET_ALIBS)
$(Q)$(TARGET_STRIP) $@
$(LUAJIT_T): $(TARGET_O) $(LUAJIT_O) $(TARGET_DEP)
$(E) "LINK $@"
$(Q)$(TARGET_LD) $(TARGET_ALDFLAGS) -o $@ $(LUAJIT_O) $(TARGET_O) $(TARGET_ALIBS)
$(Q)$(TARGET_STRIP) $@
$(E) "OK Successfully built LuaJIT"
##############################################################################
-226
View File
@@ -1,226 +0,0 @@
lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
lj_lib.h lj_libdef.h
lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h
lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
lj_libdef.h
lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h \
lj_ctype.h lj_cparse.h lj_cdata.h lj_cconv.h lj_carith.h lj_ccall.h \
lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_ff.h lj_ffdef.h \
lj_lib.h lj_libdef.h
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
lj_target_*.h lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h luajit.h \
lj_libdef.h
lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_libdef.h
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h lj_char.h \
lj_lib.h lj_libdef.h
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
lj_libdef.h
lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h
lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \
lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
lj_asm_*.h
lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
lj_bcdef.h
lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_bc.h lj_ctype.h \
lj_cdata.h lualib.h lj_lex.h lj_bcdump.h lj_state.h
lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h lj_ir.h \
lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_carith.h
lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
lj_traceerr.h
lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
lj_bc.h lj_ctype.h lj_cconv.h lj_ccall.h lj_ccallback.h lj_target.h \
lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \
lj_traceerr.h lj_vm.h
lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
lj_ccallback.h
lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
lj_cdata.h
lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_clib.h
lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h lj_frame.h \
lj_bc.h lj_vm.h lj_char.h lj_strscan.h
lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \
lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ff.h \
lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \
lj_crecord.h
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \
lj_bc.h lj_jit.h lj_ir.h
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \
lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \
lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_vm.h luajit.h
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
lj_traceerr.h lj_vm.h
lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
lj_vm.h lj_strscan.h lj_recdef.h
lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
lj_traceerr.h lj_vm.h
lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h \
lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h \
lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \
lj_ir.h lj_dispatch.h
lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
lj_vm.h lj_strscan.h lj_lib.h
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \
lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lib.h
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_func.h lj_frame.h \
lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \
lj_traceerr.h lj_vm.h
lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
lj_vm.h lj_strscan.h
lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h
lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \
lj_strscan.h lj_folddef.h
lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
lj_traceerr.h lj_vm.h lj_strscan.h
lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_ircall.h \
lj_iropt.h lj_vm.h
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h \
lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h lj_vmevent.h
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h \
lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h lj_record.h \
lj_ffrecord.h lj_snap.h lj_vm.h
lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
lj_target_*.h lj_ctype.h lj_cdata.h
lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_meta.h \
lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h
lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_char.h
lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_char.h lj_strscan.h
lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_tab.h
lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_udata.h
lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
lj_vm.h lj_vmevent.h
lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_vm.h
ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \
lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \
lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
lj_debug.h lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h \
lj_obj.c lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h \
lj_debug.c lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c lj_ccallback.h \
luajit.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c lj_api.c \
lj_lex.c lualib.h lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h \
lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c \
lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h lj_target_*.h \
lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h lj_cparse.c \
lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h lj_iropt.h \
lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \
lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c \
lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \
lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \
lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \
lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
lib_init.c
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
lj_ircall.h lj_ir.h lj_jit.h lj_frame.h lj_bc.h lj_dispatch.h lj_ctype.h \
lj_gc.h lj_ccall.h lj_ctype.h luajit.h \
host/buildvm_arch.h lj_traceerr.h
host/buildvm_asm.o: host/buildvm_asm.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_bc.h lj_def.h lj_arch.h
host/buildvm_fold.o: host/buildvm_fold.c host/buildvm.h lj_def.h lua.h \
luaconf.h lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_ir.h lj_obj.h
host/buildvm_lib.o: host/buildvm_lib.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_lib.h lj_obj.h
host/buildvm_peobj.o: host/buildvm_peobj.c host/buildvm.h lj_def.h lua.h \
luaconf.h lj_arch.h lj_bc.h lj_def.h lj_arch.h
host/minilua.o: host/minilua.c
-20
View File
@@ -1,20 +0,0 @@
----------------------------------------------------------------------------
-- LuaJIT MIPSEL disassembler wrapper module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local require = require
module(...)
local dis_mips = require(_PACKAGE.."dis_mips")
create = dis_mips.create_el
disass = dis_mips.disass_el
regname = dis_mips.regname
-20
View File
@@ -1,20 +0,0 @@
----------------------------------------------------------------------------
-- LuaJIT x64 disassembler wrapper module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the 64 bit functions from the combined
-- x86/x64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local require = require
module(...)
local dis_x86 = require(_PACKAGE.."dis_x86")
create = dis_x86.create64
disass = dis_x86.disass64
regname = dis_x86.regname64
-74
View File
@@ -1,74 +0,0 @@
/*
** Bit manipulation library.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/
#define lib_bit_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_err.h"
#include "lj_str.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_bit
LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT)
{
lj_lib_checknumber(L, 1);
return FFH_RETRY;
}
LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
{
lj_lib_checknumber(L, 1);
lj_lib_checkbit(L, 2);
return FFH_RETRY;
}
LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
LJLIB_ASM_(bit_rol) LJLIB_REC(bit_shift IR_BROL)
LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
{
int i = 0;
do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
return FFH_RETRY;
}
LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
/* ------------------------------------------------------------------------ */
LJLIB_CF(bit_tohex)
{
uint32_t b = (uint32_t)lj_lib_checkbit(L, 1);
int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2);
const char *hexdigits = "0123456789abcdef";
char buf[8];
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
if (n > 8) n = 8;
for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
lua_pushlstring(L, buf, (size_t)n);
return 1;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_bit(lua_State *L)
{
LJ_LIB_REG(L, LUA_BITLIBNAME, bit);
return 1;
}
-940
View File
@@ -1,940 +0,0 @@
/*
** String library.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#include <stdio.h>
#define lib_string_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_meta.h"
#include "lj_state.h"
#include "lj_ff.h"
#include "lj_bcdump.h"
#include "lj_char.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_string
LJLIB_ASM(string_len) LJLIB_REC(.)
{
lj_lib_checkstr(L, 1);
return FFH_RETRY;
}
LJLIB_ASM(string_byte) LJLIB_REC(string_range 0)
{
GCstr *s = lj_lib_checkstr(L, 1);
int32_t len = (int32_t)s->len;
int32_t start = lj_lib_optint(L, 2, 1);
int32_t stop = lj_lib_optint(L, 3, start);
int32_t n, i;
const unsigned char *p;
if (stop < 0) stop += len+1;
if (start < 0) start += len+1;
if (start <= 0) start = 1;
if (stop > len) stop = len;
if (start > stop) return FFH_RES(0); /* Empty interval: return no results. */
start--;
n = stop - start;
if ((uint32_t)n > LUAI_MAXCSTACK)
lj_err_caller(L, LJ_ERR_STRSLC);
lj_state_checkstack(L, (MSize)n);
p = (const unsigned char *)strdata(s) + start;
for (i = 0; i < n; i++)
setintV(L->base + i-1, p[i]);
return FFH_RES(n);
}
LJLIB_ASM(string_char)
{
int i, nargs = (int)(L->top - L->base);
char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, (size_t)nargs);
for (i = 1; i <= nargs; i++) {
int32_t k = lj_lib_checkint(L, i);
if (!checku8(k))
lj_err_arg(L, i, LJ_ERR_BADVAL);
buf[i-1] = (char)k;
}
setstrV(L, L->base-1, lj_str_new(L, buf, (size_t)nargs));
return FFH_RES(1);
}
LJLIB_ASM(string_sub) LJLIB_REC(string_range 1)
{
lj_lib_checkstr(L, 1);
lj_lib_checkint(L, 2);
setintV(L->base+2, lj_lib_optint(L, 3, -1));
return FFH_RETRY;
}
LJLIB_ASM(string_rep)
{
GCstr *s = lj_lib_checkstr(L, 1);
int32_t k = lj_lib_checkint(L, 2);
GCstr *sep = lj_lib_optstr(L, 3);
int32_t len = (int32_t)s->len;
global_State *g = G(L);
int64_t tlen;
const char *src;
char *buf;
if (k <= 0) {
empty:
setstrV(L, L->base-1, &g->strempty);
return FFH_RES(1);
}
if (sep) {
tlen = (int64_t)len + sep->len;
if (tlen > LJ_MAX_STR)
lj_err_caller(L, LJ_ERR_STROV);
tlen *= k;
if (tlen > LJ_MAX_STR)
lj_err_caller(L, LJ_ERR_STROV);
} else {
tlen = (int64_t)k * len;
if (tlen > LJ_MAX_STR)
lj_err_caller(L, LJ_ERR_STROV);
}
if (tlen == 0) goto empty;
buf = lj_str_needbuf(L, &g->tmpbuf, (MSize)tlen);
src = strdata(s);
if (sep) {
tlen -= sep->len; /* Ignore trailing separator. */
if (k > 1) { /* Paste one string and one separator. */
int32_t i;
i = 0; while (i < len) *buf++ = src[i++];
src = strdata(sep); len = sep->len;
i = 0; while (i < len) *buf++ = src[i++];
src = g->tmpbuf.buf; len += s->len; k--; /* Now copy that k-1 times. */
}
}
do {
int32_t i = 0;
do { *buf++ = src[i++]; } while (i < len);
} while (--k > 0);
setstrV(L, L->base-1, lj_str_new(L, g->tmpbuf.buf, (size_t)tlen));
return FFH_RES(1);
}
LJLIB_ASM(string_reverse)
{
GCstr *s = lj_lib_checkstr(L, 1);
lj_str_needbuf(L, &G(L)->tmpbuf, s->len);
return FFH_RETRY;
}
LJLIB_ASM_(string_lower)
LJLIB_ASM_(string_upper)
/* ------------------------------------------------------------------------ */
static int writer_buf(lua_State *L, const void *p, size_t size, void *b)
{
luaL_addlstring((luaL_Buffer *)b, (const char *)p, size);
UNUSED(L);
return 0;
}
LJLIB_CF(string_dump)
{
GCfunc *fn = lj_lib_checkfunc(L, 1);
int strip = L->base+1 < L->top && tvistruecond(L->base+1);
luaL_Buffer b;
L->top = L->base+1;
luaL_buffinit(L, &b);
if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, &b, strip))
lj_err_caller(L, LJ_ERR_STRDUMP);
luaL_pushresult(&b);
return 1;
}
/* ------------------------------------------------------------------------ */
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
#define CAP_UNFINISHED (-1)
#define CAP_POSITION (-2)
typedef struct MatchState {
const char *src_init; /* init of source string */
const char *src_end; /* end (`\0') of source string */
lua_State *L;
int level; /* total number of captures (finished or unfinished) */
int depth;
struct {
const char *init;
ptrdiff_t len;
} capture[LUA_MAXCAPTURES];
} MatchState;
#define L_ESC '%'
#define SPECIALS "^$*+?.([%-"
static int check_capture(MatchState *ms, int l)
{
l -= '1';
if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
lj_err_caller(ms->L, LJ_ERR_STRCAPI);
return l;
}
static int capture_to_close(MatchState *ms)
{
int level = ms->level;
for (level--; level>=0; level--)
if (ms->capture[level].len == CAP_UNFINISHED) return level;
lj_err_caller(ms->L, LJ_ERR_STRPATC);
return 0; /* unreachable */
}
static const char *classend(MatchState *ms, const char *p)
{
switch (*p++) {
case L_ESC:
if (*p == '\0')
lj_err_caller(ms->L, LJ_ERR_STRPATE);
return p+1;
case '[':
if (*p == '^') p++;
do { /* look for a `]' */
if (*p == '\0')
lj_err_caller(ms->L, LJ_ERR_STRPATM);
if (*(p++) == L_ESC && *p != '\0')
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
return p+1;
default:
return p;
}
}
static const unsigned char match_class_map[32] = {
0,LJ_CHAR_ALPHA,0,LJ_CHAR_CNTRL,LJ_CHAR_DIGIT,0,0,LJ_CHAR_GRAPH,0,0,0,0,
LJ_CHAR_LOWER,0,0,0,LJ_CHAR_PUNCT,0,0,LJ_CHAR_SPACE,0,
LJ_CHAR_UPPER,0,LJ_CHAR_ALNUM,LJ_CHAR_XDIGIT,0,0,0,0,0,0,0
};
static int match_class(int c, int cl)
{
if ((cl & 0xc0) == 0x40) {
int t = match_class_map[(cl&0x1f)];
if (t) {
t = lj_char_isa(c, t);
return (cl & 0x20) ? t : !t;
}
if (cl == 'z') return c == 0;
if (cl == 'Z') return c != 0;
}
return (cl == c);
}
static int matchbracketclass(int c, const char *p, const char *ec)
{
int sig = 1;
if (*(p+1) == '^') {
sig = 0;
p++; /* skip the `^' */
}
while (++p < ec) {
if (*p == L_ESC) {
p++;
if (match_class(c, uchar(*p)))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < ec)) {
p+=2;
if (uchar(*(p-2)) <= c && c <= uchar(*p))
return sig;
}
else if (uchar(*p) == c) return sig;
}
return !sig;
}
static int singlematch(int c, const char *p, const char *ep)
{
switch (*p) {
case '.': return 1; /* matches any char */
case L_ESC: return match_class(c, uchar(*(p+1)));
case '[': return matchbracketclass(c, p, ep-1);
default: return (uchar(*p) == c);
}
}
static const char *match(MatchState *ms, const char *s, const char *p);
static const char *matchbalance(MatchState *ms, const char *s, const char *p)
{
if (*p == 0 || *(p+1) == 0)
lj_err_caller(ms->L, LJ_ERR_STRPATU);
if (*s != *p) {
return NULL;
} else {
int b = *p;
int e = *(p+1);
int cont = 1;
while (++s < ms->src_end) {
if (*s == e) {
if (--cont == 0) return s+1;
} else if (*s == b) {
cont++;
}
}
}
return NULL; /* string ends out of balance */
}
static const char *max_expand(MatchState *ms, const char *s,
const char *p, const char *ep)
{
ptrdiff_t i = 0; /* counts maximum expand for item */
while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i>=0) {
const char *res = match(ms, (s+i), ep+1);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return NULL;
}
static const char *min_expand(MatchState *ms, const char *s,
const char *p, const char *ep)
{
for (;;) {
const char *res = match(ms, s, ep+1);
if (res != NULL)
return res;
else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
s++; /* try with one more repetition */
else
return NULL;
}
}
static const char *start_capture(MatchState *ms, const char *s,
const char *p, int what)
{
const char *res;
int level = ms->level;
if (level >= LUA_MAXCAPTURES) lj_err_caller(ms->L, LJ_ERR_STRCAPN);
ms->capture[level].init = s;
ms->capture[level].len = what;
ms->level = level+1;
if ((res=match(ms, s, p)) == NULL) /* match failed? */
ms->level--; /* undo capture */
return res;
}
static const char *end_capture(MatchState *ms, const char *s,
const char *p)
{
int l = capture_to_close(ms);
const char *res;
ms->capture[l].len = s - ms->capture[l].init; /* close capture */
if ((res = match(ms, s, p)) == NULL) /* match failed? */
ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
return res;
}
static const char *match_capture(MatchState *ms, const char *s, int l)
{
size_t len;
l = check_capture(ms, l);
len = (size_t)ms->capture[l].len;
if ((size_t)(ms->src_end-s) >= len &&
memcmp(ms->capture[l].init, s, len) == 0)
return s+len;
else
return NULL;
}
static const char *match(MatchState *ms, const char *s, const char *p)
{
if (++ms->depth > LJ_MAX_XLEVEL)
lj_err_caller(ms->L, LJ_ERR_STRPATX);
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': /* start capture */
if (*(p+1) == ')') /* position capture? */
s = start_capture(ms, s, p+2, CAP_POSITION);
else
s = start_capture(ms, s, p+1, CAP_UNFINISHED);
break;
case ')': /* end capture */
s = end_capture(ms, s, p+1);
break;
case L_ESC:
switch (*(p+1)) {
case 'b': /* balanced string? */
s = matchbalance(ms, s, p+2);
if (s == NULL) break;
p+=4;
goto init; /* else s = match(ms, s, p+4); */
case 'f': { /* frontier? */
const char *ep; char previous;
p += 2;
if (*p != '[')
lj_err_caller(ms->L, LJ_ERR_STRPATB);
ep = classend(ms, p); /* points to what is next */
previous = (s == ms->src_init) ? '\0' : *(s-1);
if (matchbracketclass(uchar(previous), p, ep-1) ||
!matchbracketclass(uchar(*s), p, ep-1)) { s = NULL; break; }
p=ep;
goto init; /* else s = match(ms, s, ep); */
}
default:
if (lj_char_isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
s = match_capture(ms, s, uchar(*(p+1)));
if (s == NULL) break;
p+=2;
goto init; /* else s = match(ms, s, p+2) */
}
goto dflt; /* case default */
}
break;
case '\0': /* end of pattern */
break; /* match succeeded */
case '$':
/* is the `$' the last char in pattern? */
if (*(p+1) != '\0') goto dflt;
if (s != ms->src_end) s = NULL; /* check end of string */
break;
default: dflt: { /* it is a pattern item */
const char *ep = classend(ms, p); /* points to what is next */
int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
switch (*ep) {
case '?': { /* optional */
const char *res;
if (m && ((res=match(ms, s+1, ep+1)) != NULL)) {
s = res;
break;
}
p=ep+1;
goto init; /* else s = match(ms, s, ep+1); */
}
case '*': /* 0 or more repetitions */
s = max_expand(ms, s, p, ep);
break;
case '+': /* 1 or more repetitions */
s = (m ? max_expand(ms, s+1, p, ep) : NULL);
break;
case '-': /* 0 or more repetitions (minimum) */
s = min_expand(ms, s, p, ep);
break;
default:
if (m) { s++; p=ep; goto init; } /* else s = match(ms, s+1, ep); */
s = NULL;
break;
}
break;
}
}
ms->depth--;
return s;
}
static const char *lmemfind(const char *s1, size_t l1,
const char *s2, size_t l2)
{
if (l2 == 0) {
return s1; /* empty strings are everywhere */
} else if (l2 > l1) {
return NULL; /* avoids a negative `l1' */
} else {
const char *init; /* to search for a `*s2' inside `s1' */
l2--; /* 1st char will be checked by `memchr' */
l1 = l1-l2; /* `s2' cannot be found after that */
while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
init++; /* 1st char is already checked */
if (memcmp(init, s2+1, l2) == 0) {
return init-1;
} else { /* correct `l1' and `s1' to try again */
l1 -= (size_t)(init-s1);
s1 = init;
}
}
return NULL; /* not found */
}
}
static void push_onecapture(MatchState *ms, int i, const char *s, const char *e)
{
if (i >= ms->level) {
if (i == 0) /* ms->level == 0, too */
lua_pushlstring(ms->L, s, (size_t)(e - s)); /* add whole match */
else
lj_err_caller(ms->L, LJ_ERR_STRCAPI);
} else {
ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED) lj_err_caller(ms->L, LJ_ERR_STRCAPU);
if (l == CAP_POSITION)
lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
else
lua_pushlstring(ms->L, ms->capture[i].init, (size_t)l);
}
}
static int push_captures(MatchState *ms, const char *s, const char *e)
{
int i;
int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
luaL_checkstack(ms->L, nlevels, "too many captures");
for (i = 0; i < nlevels; i++)
push_onecapture(ms, i, s, e);
return nlevels; /* number of strings pushed */
}
static ptrdiff_t posrelat(ptrdiff_t pos, size_t len)
{
/* relative string position: negative means back from end */
if (pos < 0) pos += (ptrdiff_t)len + 1;
return (pos >= 0) ? pos : 0;
}
static int str_find_aux(lua_State *L, int find)
{
size_t l1, l2;
const char *s = luaL_checklstring(L, 1, &l1);
const char *p = luaL_checklstring(L, 2, &l2);
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
if (init < 0) {
init = 0;
} else if ((size_t)(init) > l1) {
#if LJ_52
setnilV(L->top-1);
return 1;
#else
init = (ptrdiff_t)l1;
#endif
}
if (find && (lua_toboolean(L, 4) || /* explicit request? */
strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-(size_t)init, p, l2);
if (s2) {
lua_pushinteger(L, s2-s+1);
lua_pushinteger(L, s2-s+(ptrdiff_t)l2);
return 2;
}
} else {
MatchState ms;
int anchor = (*p == '^') ? (p++, 1) : 0;
const char *s1=s+init;
ms.L = L;
ms.src_init = s;
ms.src_end = s+l1;
do {
const char *res;
ms.level = ms.depth = 0;
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1-s+1); /* start */
lua_pushinteger(L, res-s); /* end */
return push_captures(&ms, NULL, 0) + 2;
} else {
return push_captures(&ms, s1, res);
}
}
} while (s1++ < ms.src_end && !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}
LJLIB_CF(string_find)
{
return str_find_aux(L, 1);
}
LJLIB_CF(string_match)
{
return str_find_aux(L, 0);
}
LJLIB_NOREG LJLIB_CF(string_gmatch_aux)
{
const char *p = strVdata(lj_lib_upvalue(L, 2));
GCstr *str = strV(lj_lib_upvalue(L, 1));
const char *s = strdata(str);
TValue *tvpos = lj_lib_upvalue(L, 3);
const char *src = s + tvpos->u32.lo;
MatchState ms;
ms.L = L;
ms.src_init = s;
ms.src_end = s + str->len;
for (; src <= ms.src_end; src++) {
const char *e;
ms.level = ms.depth = 0;
if ((e = match(&ms, src, p)) != NULL) {
int32_t pos = (int32_t)(e - s);
if (e == src) pos++; /* Ensure progress for empty match. */
tvpos->u32.lo = (uint32_t)pos;
return push_captures(&ms, src, e);
}
}
return 0; /* not found */
}
LJLIB_CF(string_gmatch)
{
lj_lib_checkstr(L, 1);
lj_lib_checkstr(L, 2);
L->top = L->base+3;
(L->top-1)->u64 = 0;
lj_lib_pushcc(L, lj_cf_string_gmatch_aux, FF_string_gmatch_aux, 3);
return 1;
}
static void add_s(MatchState *ms, luaL_Buffer *b, const char *s, const char *e)
{
size_t l, i;
const char *news = lua_tolstring(ms->L, 3, &l);
for (i = 0; i < l; i++) {
if (news[i] != L_ESC) {
luaL_addchar(b, news[i]);
} else {
i++; /* skip ESC */
if (!lj_char_isdigit(uchar(news[i]))) {
luaL_addchar(b, news[i]);
} else if (news[i] == '0') {
luaL_addlstring(b, s, (size_t)(e - s));
} else {
push_onecapture(ms, news[i] - '1', s, e);
luaL_addvalue(b); /* add capture to accumulated result */
}
}
}
}
static void add_value(MatchState *ms, luaL_Buffer *b,
const char *s, const char *e)
{
lua_State *L = ms->L;
switch (lua_type(L, 3)) {
case LUA_TNUMBER:
case LUA_TSTRING: {
add_s(ms, b, s, e);
return;
}
case LUA_TFUNCTION: {
int n;
lua_pushvalue(L, 3);
n = push_captures(ms, s, e);
lua_call(L, n, 1);
break;
}
case LUA_TTABLE: {
push_onecapture(ms, 0, s, e);
lua_gettable(L, 3);
break;
}
}
if (!lua_toboolean(L, -1)) { /* nil or false? */
lua_pop(L, 1);
lua_pushlstring(L, s, (size_t)(e - s)); /* keep original text */
} else if (!lua_isstring(L, -1)) {
lj_err_callerv(L, LJ_ERR_STRGSRV, luaL_typename(L, -1));
}
luaL_addvalue(b); /* add result to accumulator */
}
LJLIB_CF(string_gsub)
{
size_t srcl;
const char *src = luaL_checklstring(L, 1, &srcl);
const char *p = luaL_checkstring(L, 2);
int tr = lua_type(L, 3);
int max_s = luaL_optint(L, 4, (int)(srcl+1));
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
MatchState ms;
luaL_Buffer b;
if (!(tr == LUA_TNUMBER || tr == LUA_TSTRING ||
tr == LUA_TFUNCTION || tr == LUA_TTABLE))
lj_err_arg(L, 3, LJ_ERR_NOSFT);
luaL_buffinit(L, &b);
ms.L = L;
ms.src_init = src;
ms.src_end = src+srcl;
while (n < max_s) {
const char *e;
ms.level = ms.depth = 0;
e = match(&ms, src, p);
if (e) {
n++;
add_value(&ms, &b, src, e);
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < ms.src_end)
luaL_addchar(&b, *src++);
else
break;
if (anchor)
break;
}
luaL_addlstring(&b, src, (size_t)(ms.src_end-src));
luaL_pushresult(&b);
lua_pushinteger(L, n); /* number of substitutions */
return 2;
}
/* ------------------------------------------------------------------------ */
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
#define MAX_FMTITEM 512
/* valid flags in a format specification */
#define FMT_FLAGS "-+ #0"
/*
** maximum size of each format specification (such as '%-099.99d')
** (+10 accounts for %99.99x plus margin of error)
*/
#define MAX_FMTSPEC (sizeof(FMT_FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
static void addquoted(lua_State *L, luaL_Buffer *b, int arg)
{
GCstr *str = lj_lib_checkstr(L, arg);
int32_t len = (int32_t)str->len;
const char *s = strdata(str);
luaL_addchar(b, '"');
while (len--) {
uint32_t c = uchar(*s);
if (c == '"' || c == '\\' || c == '\n') {
luaL_addchar(b, '\\');
} else if (lj_char_iscntrl(c)) { /* This can only be 0-31 or 127. */
uint32_t d;
luaL_addchar(b, '\\');
if (c >= 100 || lj_char_isdigit(uchar(s[1]))) {
luaL_addchar(b, '0'+(c >= 100)); if (c >= 100) c -= 100;
goto tens;
} else if (c >= 10) {
tens:
d = (c * 205) >> 11; c -= d * 10; luaL_addchar(b, '0'+d);
}
c += '0';
}
luaL_addchar(b, c);
s++;
}
luaL_addchar(b, '"');
}
static const char *scanformat(lua_State *L, const char *strfrmt, char *form)
{
const char *p = strfrmt;
while (*p != '\0' && strchr(FMT_FLAGS, *p) != NULL) p++; /* skip flags */
if ((size_t)(p - strfrmt) >= sizeof(FMT_FLAGS))
lj_err_caller(L, LJ_ERR_STRFMTR);
if (lj_char_isdigit(uchar(*p))) p++; /* skip width */
if (lj_char_isdigit(uchar(*p))) p++; /* (2 digits at most) */
if (*p == '.') {
p++;
if (lj_char_isdigit(uchar(*p))) p++; /* skip precision */
if (lj_char_isdigit(uchar(*p))) p++; /* (2 digits at most) */
}
if (lj_char_isdigit(uchar(*p)))
lj_err_caller(L, LJ_ERR_STRFMTW);
*(form++) = '%';
strncpy(form, strfrmt, (size_t)(p - strfrmt + 1));
form += p - strfrmt + 1;
*form = '\0';
return p;
}
static void addintlen(char *form)
{
size_t l = strlen(form);
char spec = form[l - 1];
strcpy(form + l - 1, LUA_INTFRMLEN);
form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
}
static unsigned LUA_INTFRM_T num2intfrm(lua_State *L, int arg)
{
if (sizeof(LUA_INTFRM_T) == 4) {
return (LUA_INTFRM_T)lj_lib_checkbit(L, arg);
} else {
cTValue *o;
lj_lib_checknumber(L, arg);
o = L->base+arg-1;
if (tvisint(o))
return (LUA_INTFRM_T)intV(o);
else
return (LUA_INTFRM_T)numV(o);
}
}
static unsigned LUA_INTFRM_T num2uintfrm(lua_State *L, int arg)
{
if (sizeof(LUA_INTFRM_T) == 4) {
return (unsigned LUA_INTFRM_T)lj_lib_checkbit(L, arg);
} else {
cTValue *o;
lj_lib_checknumber(L, arg);
o = L->base+arg-1;
if (tvisint(o))
return (unsigned LUA_INTFRM_T)intV(o);
else if ((int32_t)o->u32.hi < 0)
return (unsigned LUA_INTFRM_T)(LUA_INTFRM_T)numV(o);
else
return (unsigned LUA_INTFRM_T)numV(o);
}
}
static GCstr *meta_tostring(lua_State *L, int arg)
{
TValue *o = L->base+arg-1;
cTValue *mo;
lua_assert(o < L->top); /* Caller already checks for existence. */
if (LJ_LIKELY(tvisstr(o)))
return strV(o);
if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
copyTV(L, L->top++, mo);
copyTV(L, L->top++, o);
lua_call(L, 1, 1);
L->top--;
if (tvisstr(L->top))
return strV(L->top);
o = L->base+arg-1;
copyTV(L, o, L->top);
}
if (tvisnumber(o)) {
return lj_str_fromnumber(L, o);
} else if (tvisnil(o)) {
return lj_str_newlit(L, "nil");
} else if (tvisfalse(o)) {
return lj_str_newlit(L, "false");
} else if (tvistrue(o)) {
return lj_str_newlit(L, "true");
} else {
if (tvisfunc(o) && isffunc(funcV(o)))
lj_str_pushf(L, "function: builtin#%d", funcV(o)->c.ffid);
else
lj_str_pushf(L, "%s: %p", lj_typename(o), lua_topointer(L, arg));
L->top--;
return strV(L->top);
}
}
LJLIB_CF(string_format)
{
int arg = 1, top = (int)(L->top - L->base);
GCstr *fmt = lj_lib_checkstr(L, arg);
const char *strfrmt = strdata(fmt);
const char *strfrmt_end = strfrmt + fmt->len;
luaL_Buffer b;
luaL_buffinit(L, &b);
while (strfrmt < strfrmt_end) {
if (*strfrmt != L_ESC) {
luaL_addchar(&b, *strfrmt++);
} else if (*++strfrmt == L_ESC) {
luaL_addchar(&b, *strfrmt++); /* %% */
} else { /* format item */
char form[MAX_FMTSPEC]; /* to store the format (`%...') */
char buff[MAX_FMTITEM]; /* to store the formatted item */
if (++arg > top)
luaL_argerror(L, arg, lj_obj_typename[0]);
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c':
sprintf(buff, form, lj_lib_checkint(L, arg));
break;
case 'd': case 'i':
addintlen(form);
sprintf(buff, form, num2intfrm(L, arg));
break;
case 'o': case 'u': case 'x': case 'X':
addintlen(form);
sprintf(buff, form, num2uintfrm(L, arg));
break;
case 'e': case 'E': case 'f': case 'g': case 'G': case 'a': case 'A': {
TValue tv;
tv.n = lj_lib_checknum(L, arg);
if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) {
/* Canonicalize output of non-finite values. */
char *p, nbuf[LJ_STR_NUMBUF];
size_t len = lj_str_bufnum(nbuf, &tv);
if (strfrmt[-1] < 'a') {
nbuf[len-3] = nbuf[len-3] - 0x20;
nbuf[len-2] = nbuf[len-2] - 0x20;
nbuf[len-1] = nbuf[len-1] - 0x20;
}
nbuf[len] = '\0';
for (p = form; *p < 'A' && *p != '.'; p++) ;
*p++ = 's'; *p = '\0';
sprintf(buff, form, nbuf);
break;
}
sprintf(buff, form, (double)tv.n);
break;
}
case 'q':
addquoted(L, &b, arg);
continue;
case 'p':
lj_str_pushf(L, "%p", lua_topointer(L, arg));
luaL_addvalue(&b);
continue;
case 's': {
GCstr *str = meta_tostring(L, arg);
if (!strchr(form, '.') && str->len >= 100) {
/* no precision and string is too long to be formatted;
keep original string */
setstrV(L, L->top++, str);
luaL_addvalue(&b);
continue;
}
sprintf(buff, form, strdata(str));
break;
}
default:
lj_err_callerv(L, LJ_ERR_STRFMTO, *(strfrmt -1));
break;
}
luaL_addlstring(&b, buff, strlen(buff));
}
}
luaL_pushresult(&b);
return 1;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_string(lua_State *L)
{
GCtab *mt;
global_State *g;
LJ_LIB_REG(L, LUA_STRLIBNAME, string);
#if defined(LUA_COMPAT_GFIND) && !LJ_52
lua_getfield(L, -1, "gmatch");
lua_setfield(L, -2, "gfind");
#endif
mt = lj_tab_new(L, 0, 1);
/* NOBARRIER: basemt is a GC root. */
g = G(L);
setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt));
settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1));
mt->nomm = (uint8_t)(~(1u<<MM_index));
return 1;
}
-300
View File
@@ -1,300 +0,0 @@
/*
** Table library.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lib_table_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_tab.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_table
LJLIB_CF(table_foreachi)
{
GCtab *t = lj_lib_checktab(L, 1);
GCfunc *func = lj_lib_checkfunc(L, 2);
MSize i, n = lj_tab_len(t);
for (i = 1; i <= n; i++) {
cTValue *val;
setfuncV(L, L->top, func);
setintV(L->top+1, i);
val = lj_tab_getint(t, (int32_t)i);
if (val) { copyTV(L, L->top+2, val); } else { setnilV(L->top+2); }
L->top += 3;
lua_call(L, 2, 1);
if (!tvisnil(L->top-1))
return 1;
L->top--;
}
return 0;
}
LJLIB_CF(table_foreach)
{
GCtab *t = lj_lib_checktab(L, 1);
GCfunc *func = lj_lib_checkfunc(L, 2);
L->top = L->base+3;
setnilV(L->top-1);
while (lj_tab_next(L, t, L->top-1)) {
copyTV(L, L->top+2, L->top);
copyTV(L, L->top+1, L->top-1);
setfuncV(L, L->top, func);
L->top += 3;
lua_call(L, 2, 1);
if (!tvisnil(L->top-1))
return 1;
L->top--;
}
return 0;
}
LJLIB_ASM(table_getn) LJLIB_REC(.)
{
lj_lib_checktab(L, 1);
return FFH_UNREACHABLE;
}
LJLIB_CF(table_maxn)
{
GCtab *t = lj_lib_checktab(L, 1);
TValue *array = tvref(t->array);
Node *node;
lua_Number m = 0;
ptrdiff_t i;
for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
if (!tvisnil(&array[i])) {
m = (lua_Number)(int32_t)i;
break;
}
node = noderef(t->node);
for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
if (!tvisnil(&node[i].val) && tvisnumber(&node[i].key)) {
lua_Number n = numberVnum(&node[i].key);
if (n > m) m = n;
}
setnumV(L->top-1, m);
return 1;
}
LJLIB_CF(table_insert) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t n, i = (int32_t)lj_tab_len(t) + 1;
int nargs = (int)((char *)L->top - (char *)L->base);
if (nargs != 2*sizeof(TValue)) {
if (nargs != 3*sizeof(TValue))
lj_err_caller(L, LJ_ERR_TABINS);
/* NOBARRIER: This just moves existing elements around. */
for (n = lj_lib_checkint(L, 2); i > n; i--) {
/* The set may invalidate the get pointer, so need to do it first! */
TValue *dst = lj_tab_setint(L, t, i);
cTValue *src = lj_tab_getint(t, i-1);
if (src) {
copyTV(L, dst, src);
} else {
setnilV(dst);
}
}
i = n;
}
{
TValue *dst = lj_tab_setint(L, t, i);
copyTV(L, dst, L->top-1); /* Set new value. */
lj_gc_barriert(L, t, dst);
}
return 0;
}
LJLIB_CF(table_remove) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t e = (int32_t)lj_tab_len(t);
int32_t pos = lj_lib_optint(L, 2, e);
if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
return 0;
lua_rawgeti(L, 1, pos); /* Get previous value. */
/* NOBARRIER: This just moves existing elements around. */
for (; pos < e; pos++) {
cTValue *src = lj_tab_getint(t, pos+1);
TValue *dst = lj_tab_setint(L, t, pos);
if (src) {
copyTV(L, dst, src);
} else {
setnilV(dst);
}
}
setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
return 1; /* Return previous value. */
}
LJLIB_CF(table_concat)
{
luaL_Buffer b;
GCtab *t = lj_lib_checktab(L, 1);
GCstr *sep = lj_lib_optstr(L, 2);
MSize seplen = sep ? sep->len : 0;
int32_t i = lj_lib_optint(L, 3, 1);
int32_t e = L->base+3 < L->top ? lj_lib_checkint(L, 4) :
(int32_t)lj_tab_len(t);
luaL_buffinit(L, &b);
if (i <= e) {
for (;;) {
cTValue *o;
lua_rawgeti(L, 1, i);
o = L->top-1;
if (!(tvisstr(o) || tvisnumber(o)))
lj_err_callerv(L, LJ_ERR_TABCAT, lj_typename(o), i);
luaL_addvalue(&b);
if (i++ == e) break;
if (seplen)
luaL_addlstring(&b, strdata(sep), seplen);
}
}
luaL_pushresult(&b);
return 1;
}
/* ------------------------------------------------------------------------ */
static void set2(lua_State *L, int i, int j)
{
lua_rawseti(L, 1, i);
lua_rawseti(L, 1, j);
}
static int sort_comp(lua_State *L, int a, int b)
{
if (!lua_isnil(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
lua_call(L, 2, 1);
res = lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
} else { /* a < b? */
return lua_lessthan(L, a, b);
}
}
static void auxsort(lua_State *L, int l, int u)
{
while (l < u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
lua_rawgeti(L, 1, l);
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
set2(L, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
lua_rawgeti(L, 1, i);
lua_rawgeti(L, 1, l);
if (sort_comp(L, -2, -1)) { /* a[i]<a[l]? */
set2(L, i, l);
} else {
lua_pop(L, 1); /* remove a[l] */
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
set2(L, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
lua_rawgeti(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
lua_rawgeti(L, 1, u-1);
set2(L, i, u-1);
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= P */
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i>=u) lj_err_caller(L, LJ_ERR_TABSORT);
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] <= P */
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
if (j<=l) lj_err_caller(L, LJ_ERR_TABSORT);
lua_pop(L, 1); /* remove a[j] */
}
if (j<i) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
set2(L, i, j);
}
lua_rawgeti(L, 1, u-1);
lua_rawgeti(L, 1, i);
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller half is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
j=l; i=i-1; l=i+2;
} else {
j=i+1; i=u; u=j-2;
}
auxsort(L, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
LJLIB_CF(table_sort)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t n = (int32_t)lj_tab_len(t);
lua_settop(L, 2);
if (!tvisnil(L->base+1))
lj_lib_checkfunc(L, 2);
auxsort(L, 1, n);
return 0;
}
#if LJ_52
LJLIB_PUSH("n")
LJLIB_CF(table_pack)
{
TValue *array, *base = L->base;
MSize i, n = (uint32_t)(L->top - base);
GCtab *t = lj_tab_new(L, n ? n+1 : 0, 1);
/* NOBARRIER: The table is new (marked white). */
setintV(lj_tab_setstr(L, t, strV(lj_lib_upvalue(L, 1))), (int32_t)n);
for (array = tvref(t->array) + 1, i = 0; i < n; i++)
copyTV(L, &array[i], &base[i]);
settabV(L, base, t);
L->top = base+1;
lj_gc_check(L);
return 1;
}
#endif
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_table(lua_State *L)
{
LJ_LIB_REG(L, LUA_TABLIBNAME, table);
#if LJ_52
lua_getglobal(L, "unpack");
lua_setfield(L, -2, "unpack");
#endif
return 1;
}
-26
View File
@@ -1,26 +0,0 @@
# Valgrind suppression file for LuaJIT 2.0.
{
Optimized string compare
Memcheck:Addr4
fun:lj_str_cmp
}
{
Optimized string compare
Memcheck:Addr1
fun:lj_str_cmp
}
{
Optimized string compare
Memcheck:Addr4
fun:lj_str_new
}
{
Optimized string compare
Memcheck:Addr1
fun:lj_str_new
}
{
Optimized string compare
Memcheck:Cond
fun:lj_str_new
}
-419
View File
@@ -1,419 +0,0 @@
/*
** Target architecture selection.
** Copyright (C) 2005-2013 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_PPC 4
#define LUAJIT_ARCH_ppc 4
#define LUAJIT_ARCH_PPCSPE 5
#define LUAJIT_ARCH_ppcspe 5
#define LUAJIT_ARCH_MIPS 6
#define LUAJIT_ARCH_mips 6
/* 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(__ppc__) || defined(__ppc) || defined(__PPC__) || defined(__PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__POWERPC) || defined(_M_PPC)
#ifdef __NO_FPRS__
#define LUAJIT_TARGET LUAJIT_ARCH_PPCSPE
#else
#define LUAJIT_TARGET LUAJIT_ARCH_PPC
#endif
#elif defined(__mips__) || defined(__mips) || defined(__MIPS__) || defined(__MIPS)
#define LUAJIT_TARGET LUAJIT_ARCH_MIPS
#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__)
#define LUAJIT_OS LUAJIT_OS_BSD
#elif (defined(__sun__) && defined(__svr4__)) || defined(__CYGWIN__)
#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)
#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
#if _XBOX_VER >= 200
#define LJ_TARGET_XBOX360 1
#define LJ_TARGET_CONSOLE 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 || __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
#define LJ_ABI_WIN LJ_TARGET_WINDOWS
#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
#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_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__
#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_PPC
#define LJ_ARCH_NAME "ppc"
#if _LP64
#define LJ_ARCH_BITS 64
#else
#define LJ_ARCH_BITS 32
#endif
#define LJ_ARCH_ENDIAN LUAJIT_BE
#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 _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 __PPC64__ || __powerpc64__ || LJ_TARGET_CONSOLE
#define LJ_ARCH_PPC64 1
#define LJ_ARCH_NOFFI 1
#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_PPCSPE
#define LJ_ARCH_NAME "ppcspe"
#define LJ_ARCH_BITS 32
#define LJ_ARCH_ENDIAN LUAJIT_BE
#ifndef LJ_ABI_SOFTFP
#define LJ_ABI_SOFTFP 1
#endif
#define LJ_ABI_EABI 1
#define LJ_TARGET_PPCSPE 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_SINGLE
#define LJ_ARCH_NOFFI 1 /* NYI: comparisons, calls. */
#define LJ_ARCH_NOJIT 1
#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
#define LJ_ARCH_NAME "mipsel"
#define LJ_ARCH_ENDIAN LUAJIT_LE
#else
#define LJ_ARCH_NAME "mips"
#define LJ_ARCH_ENDIAN LUAJIT_BE
#endif
#define LJ_ARCH_BITS 32
#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_SINGLE
#if _MIPS_ARCH_MIPS32R2
#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_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_PPC || LJ_TARGET_PPCSPE
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
#error "No support for PowerPC CPUs without double-precision FPU"
#endif
#if defined(_LITTLE_ENDIAN)
#error "No support for little-endian PowerPC"
#endif
#if defined(_LP64)
#error "No support for PowerPC 64 bit mode"
#endif
#elif LJ_TARGET_MIPS
#if defined(__mips_soft_float)
#error "No support for MIPS CPUs without FPU"
#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
/* 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
#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. */
#if (defined(__ANDROID__) && !defined(LJ_TARGET_X86ORX64)) || defined(__symbian__) || LJ_TARGET_XBOX360
#define LUAJIT_NO_LOG2
#endif
#if defined(__symbian__)
#define LUAJIT_NO_EXP2
#endif
#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3
#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
-396
View File
@@ -1,396 +0,0 @@
/*
** Bytecode writer.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/
#define lj_bcwrite_c
#define LUA_CORE
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_str.h"
#include "lj_bc.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#endif
#if LJ_HASJIT
#include "lj_dispatch.h"
#include "lj_jit.h"
#endif
#include "lj_bcdump.h"
#include "lj_vm.h"
/* Context for bytecode writer. */
typedef struct BCWriteCtx {
SBuf sb; /* Output buffer. */
lua_State *L; /* Lua state. */
GCproto *pt; /* Root prototype. */
lua_Writer wfunc; /* Writer callback. */
void *wdata; /* Writer callback data. */
int strip; /* Strip debug info. */
int status; /* Status from writer callback. */
} BCWriteCtx;
/* -- Output buffer handling ---------------------------------------------- */
/* Resize buffer if needed. */
static LJ_NOINLINE void bcwrite_resize(BCWriteCtx *ctx, MSize len)
{
MSize sz = ctx->sb.sz * 2;
while (ctx->sb.n + len > sz) sz = sz * 2;
lj_str_resizebuf(ctx->L, &ctx->sb, sz);
}
/* Need a certain amount of buffer space. */
static LJ_AINLINE void bcwrite_need(BCWriteCtx *ctx, MSize len)
{
if (LJ_UNLIKELY(ctx->sb.n + len > ctx->sb.sz))
bcwrite_resize(ctx, len);
}
/* Add memory block to buffer. */
static void bcwrite_block(BCWriteCtx *ctx, const void *p, MSize len)
{
uint8_t *q = (uint8_t *)(ctx->sb.buf + ctx->sb.n);
MSize i;
ctx->sb.n += len;
for (i = 0; i < len; i++) q[i] = ((uint8_t *)p)[i];
}
/* Add byte to buffer. */
static LJ_AINLINE void bcwrite_byte(BCWriteCtx *ctx, uint8_t b)
{
ctx->sb.buf[ctx->sb.n++] = b;
}
/* Add ULEB128 value to buffer. */
static void bcwrite_uleb128(BCWriteCtx *ctx, uint32_t v)
{
MSize n = ctx->sb.n;
uint8_t *p = (uint8_t *)ctx->sb.buf;
for (; v >= 0x80; v >>= 7)
p[n++] = (uint8_t)((v & 0x7f) | 0x80);
p[n++] = (uint8_t)v;
ctx->sb.n = n;
}
/* -- Bytecode writer ----------------------------------------------------- */
/* Write a single constant key/value of a template table. */
static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
{
bcwrite_need(ctx, 1+10);
if (tvisstr(o)) {
const GCstr *str = strV(o);
MSize len = str->len;
bcwrite_need(ctx, 5+len);
bcwrite_uleb128(ctx, BCDUMP_KTAB_STR+len);
bcwrite_block(ctx, strdata(str), len);
} else if (tvisint(o)) {
bcwrite_byte(ctx, BCDUMP_KTAB_INT);
bcwrite_uleb128(ctx, intV(o));
} else if (tvisnum(o)) {
if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */
lua_Number num = numV(o);
int32_t k = lj_num2int(num);
if (num == (lua_Number)k) { /* -0 is never a constant. */
bcwrite_byte(ctx, BCDUMP_KTAB_INT);
bcwrite_uleb128(ctx, k);
return;
}
}
bcwrite_byte(ctx, BCDUMP_KTAB_NUM);
bcwrite_uleb128(ctx, o->u32.lo);
bcwrite_uleb128(ctx, o->u32.hi);
} else {
lua_assert(tvispri(o));
bcwrite_byte(ctx, BCDUMP_KTAB_NIL+~itype(o));
}
}
/* Write a template table. */
static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t)
{
MSize narray = 0, nhash = 0;
if (t->asize > 0) { /* Determine max. length of array part. */
ptrdiff_t i;
TValue *array = tvref(t->array);
for (i = (ptrdiff_t)t->asize-1; i >= 0; i--)
if (!tvisnil(&array[i]))
break;
narray = (MSize)(i+1);
}
if (t->hmask > 0) { /* Count number of used hash slots. */
MSize i, hmask = t->hmask;
Node *node = noderef(t->node);
for (i = 0; i <= hmask; i++)
nhash += !tvisnil(&node[i].val);
}
/* Write number of array slots and hash slots. */
bcwrite_uleb128(ctx, narray);
bcwrite_uleb128(ctx, nhash);
if (narray) { /* Write array entries (may contain nil). */
MSize i;
TValue *o = tvref(t->array);
for (i = 0; i < narray; i++, o++)
bcwrite_ktabk(ctx, o, 1);
}
if (nhash) { /* Write hash entries. */
MSize i = nhash;
Node *node = noderef(t->node) + t->hmask;
for (;; node--)
if (!tvisnil(&node->val)) {
bcwrite_ktabk(ctx, &node->key, 0);
bcwrite_ktabk(ctx, &node->val, 1);
if (--i == 0) break;
}
}
}
/* Write GC constants of a prototype. */
static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
{
MSize i, sizekgc = pt->sizekgc;
GCRef *kr = mref(pt->k, GCRef) - (ptrdiff_t)sizekgc;
for (i = 0; i < sizekgc; i++, kr++) {
GCobj *o = gcref(*kr);
MSize tp, need = 1;
/* Determine constant type and needed size. */
if (o->gch.gct == ~LJ_TSTR) {
tp = BCDUMP_KGC_STR + gco2str(o)->len;
need = 5+gco2str(o)->len;
} else if (o->gch.gct == ~LJ_TPROTO) {
lua_assert((pt->flags & PROTO_CHILD));
tp = BCDUMP_KGC_CHILD;
#if LJ_HASFFI
} else if (o->gch.gct == ~LJ_TCDATA) {
CTypeID id = gco2cd(o)->ctypeid;
need = 1+4*5;
if (id == CTID_INT64) {
tp = BCDUMP_KGC_I64;
} else if (id == CTID_UINT64) {
tp = BCDUMP_KGC_U64;
} else {
lua_assert(id == CTID_COMPLEX_DOUBLE);
tp = BCDUMP_KGC_COMPLEX;
}
#endif
} else {
lua_assert(o->gch.gct == ~LJ_TTAB);
tp = BCDUMP_KGC_TAB;
need = 1+2*5;
}
/* Write constant type. */
bcwrite_need(ctx, need);
bcwrite_uleb128(ctx, tp);
/* Write constant data (if any). */
if (tp >= BCDUMP_KGC_STR) {
bcwrite_block(ctx, strdata(gco2str(o)), gco2str(o)->len);
} else if (tp == BCDUMP_KGC_TAB) {
bcwrite_ktab(ctx, gco2tab(o));
#if LJ_HASFFI
} else if (tp != BCDUMP_KGC_CHILD) {
cTValue *p = (TValue *)cdataptr(gco2cd(o));
bcwrite_uleb128(ctx, p[0].u32.lo);
bcwrite_uleb128(ctx, p[0].u32.hi);
if (tp == BCDUMP_KGC_COMPLEX) {
bcwrite_uleb128(ctx, p[1].u32.lo);
bcwrite_uleb128(ctx, p[1].u32.hi);
}
#endif
}
}
}
/* Write number constants of a prototype. */
static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
{
MSize i, sizekn = pt->sizekn;
cTValue *o = mref(pt->k, TValue);
bcwrite_need(ctx, 10*sizekn);
for (i = 0; i < sizekn; i++, o++) {
int32_t k;
if (tvisint(o)) {
k = intV(o);
goto save_int;
} else {
/* Write a 33 bit ULEB128 for the int (lsb=0) or loword (lsb=1). */
if (!LJ_DUALNUM) { /* Narrow number constants to integers. */
lua_Number num = numV(o);
k = lj_num2int(num);
if (num == (lua_Number)k) { /* -0 is never a constant. */
save_int:
bcwrite_uleb128(ctx, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u));
if (k < 0) {
char *p = &ctx->sb.buf[ctx->sb.n-1];
*p = (*p & 7) | ((k>>27) & 0x18);
}
continue;
}
}
bcwrite_uleb128(ctx, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u)));
if (o->u32.lo >= 0x80000000u) {
char *p = &ctx->sb.buf[ctx->sb.n-1];
*p = (*p & 7) | ((o->u32.lo>>27) & 0x18);
}
bcwrite_uleb128(ctx, o->u32.hi);
}
}
}
/* Write bytecode instructions. */
static void bcwrite_bytecode(BCWriteCtx *ctx, GCproto *pt)
{
MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */
#if LJ_HASJIT
uint8_t *p = (uint8_t *)&ctx->sb.buf[ctx->sb.n];
#endif
bcwrite_block(ctx, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns));
#if LJ_HASJIT
/* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
if ((pt->flags & PROTO_ILOOP) || pt->trace) {
jit_State *J = L2J(ctx->L);
MSize i;
for (i = 0; i < nbc; i++, p += sizeof(BCIns)) {
BCOp op = (BCOp)p[LJ_ENDIAN_SELECT(0, 3)];
if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP ||
op == BC_JFORI) {
p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL);
} else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) {
BCReg rd = p[LJ_ENDIAN_SELECT(2, 1)] + (p[LJ_ENDIAN_SELECT(3, 0)] << 8);
BCIns ins = traceref(J, rd)->startins;
p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL);
p[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins);
p[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins);
}
}
}
#endif
}
/* Write prototype. */
static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
{
MSize sizedbg = 0;
/* Recursively write children of prototype. */
if ((pt->flags & PROTO_CHILD)) {
ptrdiff_t i, n = pt->sizekgc;
GCRef *kr = mref(pt->k, GCRef) - 1;
for (i = 0; i < n; i++, kr--) {
GCobj *o = gcref(*kr);
if (o->gch.gct == ~LJ_TPROTO)
bcwrite_proto(ctx, gco2pt(o));
}
}
/* Start writing the prototype info to a buffer. */
lj_str_resetbuf(&ctx->sb);
ctx->sb.n = 5; /* Leave room for final size. */
bcwrite_need(ctx, 4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2);
/* Write prototype header. */
bcwrite_byte(ctx, (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)));
bcwrite_byte(ctx, pt->numparams);
bcwrite_byte(ctx, pt->framesize);
bcwrite_byte(ctx, pt->sizeuv);
bcwrite_uleb128(ctx, pt->sizekgc);
bcwrite_uleb128(ctx, pt->sizekn);
bcwrite_uleb128(ctx, pt->sizebc-1);
if (!ctx->strip) {
if (proto_lineinfo(pt))
sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt);
bcwrite_uleb128(ctx, sizedbg);
if (sizedbg) {
bcwrite_uleb128(ctx, pt->firstline);
bcwrite_uleb128(ctx, pt->numline);
}
}
/* Write bytecode instructions and upvalue refs. */
bcwrite_bytecode(ctx, pt);
bcwrite_block(ctx, proto_uv(pt), pt->sizeuv*2);
/* Write constants. */
bcwrite_kgc(ctx, pt);
bcwrite_knum(ctx, pt);
/* Write debug info, if not stripped. */
if (sizedbg) {
bcwrite_need(ctx, sizedbg);
bcwrite_block(ctx, proto_lineinfo(pt), sizedbg);
}
/* Pass buffer to writer function. */
if (ctx->status == 0) {
MSize n = ctx->sb.n - 5;
MSize nn = (lj_fls(n)+8)*9 >> 6;
ctx->sb.n = 5 - nn;
bcwrite_uleb128(ctx, n); /* Fill in final size. */
lua_assert(ctx->sb.n == 5);
ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf+5-nn, nn+n, ctx->wdata);
}
}
/* Write header of bytecode dump. */
static void bcwrite_header(BCWriteCtx *ctx)
{
GCstr *chunkname = proto_chunkname(ctx->pt);
const char *name = strdata(chunkname);
MSize len = chunkname->len;
lj_str_resetbuf(&ctx->sb);
bcwrite_need(ctx, 5+5+len);
bcwrite_byte(ctx, BCDUMP_HEAD1);
bcwrite_byte(ctx, BCDUMP_HEAD2);
bcwrite_byte(ctx, BCDUMP_HEAD3);
bcwrite_byte(ctx, BCDUMP_VERSION);
bcwrite_byte(ctx, (ctx->strip ? BCDUMP_F_STRIP : 0) +
(LJ_BE ? BCDUMP_F_BE : 0) +
((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0));
if (!ctx->strip) {
bcwrite_uleb128(ctx, len);
bcwrite_block(ctx, name, len);
}
ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf, ctx->sb.n, ctx->wdata);
}
/* Write footer of bytecode dump. */
static void bcwrite_footer(BCWriteCtx *ctx)
{
if (ctx->status == 0) {
uint8_t zero = 0;
ctx->status = ctx->wfunc(ctx->L, &zero, 1, ctx->wdata);
}
}
/* Protected callback for bytecode writer. */
static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud)
{
BCWriteCtx *ctx = (BCWriteCtx *)ud;
UNUSED(dummy);
lj_str_resizebuf(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */
bcwrite_header(ctx);
bcwrite_proto(ctx, ctx->pt);
bcwrite_footer(ctx);
return NULL;
}
/* Write bytecode for a prototype. */
int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
int strip)
{
BCWriteCtx ctx;
int status;
ctx.L = L;
ctx.pt = pt;
ctx.wfunc = writer;
ctx.wdata = data;
ctx.strip = strip;
ctx.status = 0;
lj_str_initbuf(&ctx.sb);
status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
if (status == 0) status = ctx.status;
lj_str_freebuf(G(ctx.L), &ctx.sb);
return status;
}
-27
View File
@@ -1,27 +0,0 @@
/*
** C data arithmetic.
** Copyright (C) 2005-2013 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_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
-889
View File
@@ -1,889 +0,0 @@
/*
** Fast function call recorder.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/
#define lj_ffrecord_c
#define LUA_CORE
#include "lj_obj.h"
#if LJ_HASJIT
#include "lj_err.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_frame.h"
#include "lj_bc.h"
#include "lj_ff.h"
#include "lj_ir.h"
#include "lj_jit.h"
#include "lj_ircall.h"
#include "lj_iropt.h"
#include "lj_trace.h"
#include "lj_record.h"
#include "lj_ffrecord.h"
#include "lj_crecord.h"
#include "lj_dispatch.h"
#include "lj_vm.h"
#include "lj_strscan.h"
/* Some local macros to save typing. Undef'd at the end. */
#define IR(ref) (&J->cur.ir[(ref)])
/* Pass IR on to next optimization in chain (FOLD). */
#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
/* -- Fast function recording handlers ------------------------------------ */
/* Conventions for fast function call handlers:
**
** The argument slots start at J->base[0]. All of them are guaranteed to be
** valid and type-specialized references. J->base[J->maxslot] is set to 0
** as a sentinel. The runtime argument values start at rd->argv[0].
**
** In general fast functions should check for presence of all of their
** arguments and for the correct argument types. Some simplifications
** are allowed if the interpreter throws instead. But even if recording
** is aborted, the generated IR must be consistent (no zero-refs).
**
** The number of results in rd->nres is set to 1. Handlers that return
** a different number of results need to override it. A negative value
** prevents return processing (e.g. for pending calls).
**
** Results need to be stored starting at J->base[0]. Return processing
** moves them to the right slots later.
**
** The per-ffid auxiliary data is the value of the 2nd part of the
** LJLIB_REC() annotation. This allows handling similar functionality
** in a common handler.
*/
/* Type of handler to record a fast function. */
typedef void (LJ_FASTCALL *RecordFunc)(jit_State *J, RecordFFData *rd);
/* Get runtime value of int argument. */
static int32_t argv2int(jit_State *J, TValue *o)
{
if (!lj_strscan_numberobj(o))
lj_trace_err(J, LJ_TRERR_BADTYPE);
return tvisint(o) ? intV(o) : lj_num2int(numV(o));
}
/* Get runtime value of string argument. */
static GCstr *argv2str(jit_State *J, TValue *o)
{
if (LJ_LIKELY(tvisstr(o))) {
return strV(o);
} else {
GCstr *s;
if (!tvisnumber(o))
lj_trace_err(J, LJ_TRERR_BADTYPE);
if (tvisint(o))
s = lj_str_fromint(J->L, intV(o));
else
s = lj_str_fromnum(J->L, &o->n);
setstrV(J->L, o, s);
return s;
}
}
/* Return number of results wanted by caller. */
static ptrdiff_t results_wanted(jit_State *J)
{
TValue *frame = J->L->base-1;
if (frame_islua(frame))
return (ptrdiff_t)bc_b(frame_pc(frame)[-1]) - 1;
else
return -1;
}
/* Throw error for unsupported variant of fast function. */
LJ_NORET static void recff_nyiu(jit_State *J)
{
setfuncV(J->L, &J->errinfo, J->fn);
lj_trace_err_info(J, LJ_TRERR_NYIFFU);
}
/* Fallback handler for all fast functions that are not recorded (yet). */
static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd)
{
setfuncV(J->L, &J->errinfo, J->fn);
lj_trace_err_info(J, LJ_TRERR_NYIFF);
UNUSED(rd);
}
/* C functions can have arbitrary side-effects and are not recorded (yet). */
static void LJ_FASTCALL recff_c(jit_State *J, RecordFFData *rd)
{
setfuncV(J->L, &J->errinfo, J->fn);
lj_trace_err_info(J, LJ_TRERR_NYICF);
UNUSED(rd);
}
/* -- Base library fast functions ----------------------------------------- */
static void LJ_FASTCALL recff_assert(jit_State *J, RecordFFData *rd)
{
/* Arguments already specialized. The interpreter throws for nil/false. */
rd->nres = J->maxslot; /* Pass through all arguments. */
}
static void LJ_FASTCALL recff_type(jit_State *J, RecordFFData *rd)
{
/* Arguments already specialized. Result is a constant string. Neat, huh? */
uint32_t t;
if (tvisnumber(&rd->argv[0]))
t = ~LJ_TNUMX;
else if (LJ_64 && tvislightud(&rd->argv[0]))
t = ~LJ_TLIGHTUD;
else
t = ~itype(&rd->argv[0]);
J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[t]));
UNUSED(rd);
}
static void LJ_FASTCALL recff_getmetatable(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
if (tr) {
RecordIndex ix;
ix.tab = tr;
copyTV(J->L, &ix.tabv, &rd->argv[0]);
if (lj_record_mm_lookup(J, &ix, MM_metatable))
J->base[0] = ix.mobj;
else
J->base[0] = ix.mt;
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
TRef mt = J->base[1];
if (tref_istab(tr) && (tref_istab(mt) || (mt && tref_isnil(mt)))) {
TRef fref, mtref;
RecordIndex ix;
ix.tab = tr;
copyTV(J->L, &ix.tabv, &rd->argv[0]);
lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
fref = emitir(IRT(IR_FREF, IRT_P32), tr, IRFL_TAB_META);
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
emitir(IRT(IR_FSTORE, IRT_TAB), fref, mtref);
if (!tref_isnil(mt))
emitir(IRT(IR_TBAR, IRT_TAB), tr, 0);
J->base[0] = tr;
J->needsnap = 1;
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_rawget(jit_State *J, RecordFFData *rd)
{
RecordIndex ix;
ix.tab = J->base[0]; ix.key = J->base[1];
if (tref_istab(ix.tab) && ix.key) {
ix.val = 0; ix.idxchain = 0;
settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
copyTV(J->L, &ix.keyv, &rd->argv[1]);
J->base[0] = lj_record_idx(J, &ix);
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_rawset(jit_State *J, RecordFFData *rd)
{
RecordIndex ix;
ix.tab = J->base[0]; ix.key = J->base[1]; ix.val = J->base[2];
if (tref_istab(ix.tab) && ix.key && ix.val) {
ix.idxchain = 0;
settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
copyTV(J->L, &ix.keyv, &rd->argv[1]);
copyTV(J->L, &ix.valv, &rd->argv[2]);
lj_record_idx(J, &ix);
/* Pass through table at J->base[0] as result. */
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_rawequal(jit_State *J, RecordFFData *rd)
{
TRef tra = J->base[0];
TRef trb = J->base[1];
if (tra && trb) {
int diff = lj_record_objcmp(J, tra, trb, &rd->argv[0], &rd->argv[1]);
J->base[0] = diff ? TREF_FALSE : TREF_TRUE;
} /* else: Interpreter will throw. */
}
#if LJ_52
static void LJ_FASTCALL recff_rawlen(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
if (tref_isstr(tr))
J->base[0] = emitir(IRTI(IR_FLOAD), tr, IRFL_STR_LEN);
else if (tref_istab(tr))
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_len, tr);
/* else: Interpreter will throw. */
UNUSED(rd);
}
#endif
/* Determine mode of select() call. */
int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv)
{
if (tref_isstr(tr) && *strVdata(tv) == '#') { /* select('#', ...) */
if (strV(tv)->len == 1) {
emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv)));
} else {
TRef trptr = emitir(IRT(IR_STRREF, IRT_P32), tr, lj_ir_kint(J, 0));
TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY);
emitir(IRTG(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#'));
}
return 0;
} else { /* select(n, ...) */
int32_t start = argv2int(J, tv);
if (start == 0) lj_trace_err(J, LJ_TRERR_BADTYPE); /* A bit misleading. */
return start;
}
}
static void LJ_FASTCALL recff_select(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
if (tr) {
ptrdiff_t start = lj_ffrecord_select_mode(J, tr, &rd->argv[0]);
if (start == 0) { /* select('#', ...) */
J->base[0] = lj_ir_kint(J, J->maxslot - 1);
} else if (tref_isk(tr)) { /* select(k, ...) */
ptrdiff_t n = (ptrdiff_t)J->maxslot;
if (start < 0) start += n;
else if (start > n) start = n;
rd->nres = n - start;
if (start >= 1) {
ptrdiff_t i;
for (i = 0; i < n - start; i++)
J->base[i] = J->base[start+i];
} /* else: Interpreter will throw. */
} else {
recff_nyiu(J);
}
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
TRef base = J->base[1];
if (tr && base) {
base = lj_opt_narrow_toint(J, base);
if (!tref_isk(base) || IR(tref_ref(base))->i != 10)
recff_nyiu(J);
}
if (tref_isnumber_str(tr)) {
if (tref_isstr(tr)) {
TValue tmp;
if (!lj_strscan_num(strV(&rd->argv[0]), &tmp))
recff_nyiu(J); /* Would need an inverted STRTO for this case. */
tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
}
#if LJ_HASFFI
} else if (tref_iscdata(tr)) {
lj_crecord_tonumber(J, rd);
return;
#endif
} else {
tr = TREF_NIL;
}
J->base[0] = tr;
UNUSED(rd);
}
static TValue *recff_metacall_cp(lua_State *L, lua_CFunction dummy, void *ud)
{
jit_State *J = (jit_State *)ud;
lj_record_tailcall(J, 0, 1);
UNUSED(L); UNUSED(dummy);
return NULL;
}
static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm)
{
RecordIndex ix;
ix.tab = J->base[0];
copyTV(J->L, &ix.tabv, &rd->argv[0]);
if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
int errcode;
TValue argv0;
/* Temporarily insert metamethod below object. */
J->base[1] = J->base[0];
J->base[0] = ix.mobj;
copyTV(J->L, &argv0, &rd->argv[0]);
copyTV(J->L, &rd->argv[1], &rd->argv[0]);
copyTV(J->L, &rd->argv[0], &ix.mobjv);
/* Need to protect lj_record_tailcall because it may throw. */
errcode = lj_vm_cpcall(J->L, NULL, J, recff_metacall_cp);
/* Always undo Lua stack changes to avoid confusing the interpreter. */
copyTV(J->L, &rd->argv[0], &argv0);
if (errcode)
lj_err_throw(J->L, errcode); /* Propagate errors. */
rd->nres = -1; /* Pending call. */
return 1; /* Tailcalled to metamethod. */
}
return 0;
}
static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
if (tref_isstr(tr)) {
/* Ignore __tostring in the string base metatable. */
/* Pass on result in J->base[0]. */
} else if (!recff_metacall(J, rd, MM_tostring)) {
if (tref_isnumber(tr)) {
J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
} else if (tref_ispri(tr)) {
J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)]));
} else {
recff_nyiu(J);
}
}
}
static void LJ_FASTCALL recff_ipairs_aux(jit_State *J, RecordFFData *rd)
{
RecordIndex ix;
ix.tab = J->base[0];
if (tref_istab(ix.tab)) {
if (!tvisnumber(&rd->argv[1])) /* No support for string coercion. */
lj_trace_err(J, LJ_TRERR_BADTYPE);
setintV(&ix.keyv, numberVint(&rd->argv[1])+1);
settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
ix.val = 0; ix.idxchain = 0;
ix.key = lj_opt_narrow_toint(J, J->base[1]);
J->base[0] = ix.key = emitir(IRTI(IR_ADD), ix.key, lj_ir_kint(J, 1));
J->base[1] = lj_record_idx(J, &ix);
rd->nres = tref_isnil(J->base[1]) ? 0 : 2;
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_ipairs(jit_State *J, RecordFFData *rd)
{
if (!(LJ_52 && recff_metacall(J, rd, MM_ipairs))) {
TRef tab = J->base[0];
if (tref_istab(tab)) {
J->base[0] = lj_ir_kfunc(J, funcV(&J->fn->c.upvalue[0]));
J->base[1] = tab;
J->base[2] = lj_ir_kint(J, 0);
rd->nres = 3;
} /* else: Interpreter will throw. */
}
}
static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd)
{
if (J->maxslot >= 1) {
lj_record_call(J, 0, J->maxslot - 1);
rd->nres = -1; /* Pending call. */
} /* else: Interpreter will throw. */
}
static TValue *recff_xpcall_cp(lua_State *L, lua_CFunction dummy, void *ud)
{
jit_State *J = (jit_State *)ud;
lj_record_call(J, 1, J->maxslot - 2);
UNUSED(L); UNUSED(dummy);
return NULL;
}
static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd)
{
if (J->maxslot >= 2) {
TValue argv0, argv1;
TRef tmp;
int errcode;
/* Swap function and traceback. */
tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp;
copyTV(J->L, &argv0, &rd->argv[0]);
copyTV(J->L, &argv1, &rd->argv[1]);
copyTV(J->L, &rd->argv[0], &argv1);
copyTV(J->L, &rd->argv[1], &argv0);
/* Need to protect lj_record_call because it may throw. */
errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp);
/* Always undo Lua stack swap to avoid confusing the interpreter. */
copyTV(J->L, &rd->argv[0], &argv0);
copyTV(J->L, &rd->argv[1], &argv1);
if (errcode)
lj_err_throw(J->L, errcode); /* Propagate errors. */
rd->nres = -1; /* Pending call. */
} /* else: Interpreter will throw. */
}
/* -- Math library fast functions ----------------------------------------- */
static void LJ_FASTCALL recff_math_abs(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
J->base[0] = emitir(IRTN(IR_ABS), tr, lj_ir_knum_abs(J));
UNUSED(rd);
}
/* Record rounding functions math.floor and math.ceil. */
static void LJ_FASTCALL recff_math_round(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
if (!tref_isinteger(tr)) { /* Pass through integers unmodified. */
tr = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, tr), rd->data);
/* Result is integral (or NaN/Inf), but may not fit an int32_t. */
if (LJ_DUALNUM) { /* Try to narrow using a guarded conversion to int. */
lua_Number n = lj_vm_foldfpm(numberVnum(&rd->argv[0]), rd->data);
if (n == (lua_Number)lj_num2int(n))
tr = emitir(IRTGI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_CHECK);
}
J->base[0] = tr;
}
}
/* Record unary math.* functions, mapped to IR_FPMATH opcode. */
static void LJ_FASTCALL recff_math_unary(jit_State *J, RecordFFData *rd)
{
J->base[0] = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, J->base[0]), rd->data);
}
/* Record math.log. */
static void LJ_FASTCALL recff_math_log(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
if (J->base[1]) {
#ifdef LUAJIT_NO_LOG2
uint32_t fpm = IRFPM_LOG;
#else
uint32_t fpm = IRFPM_LOG2;
#endif
TRef trb = lj_ir_tonum(J, J->base[1]);
tr = emitir(IRTN(IR_FPMATH), tr, fpm);
trb = emitir(IRTN(IR_FPMATH), trb, fpm);
trb = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), trb);
tr = emitir(IRTN(IR_MUL), tr, trb);
} else {
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_LOG);
}
J->base[0] = tr;
UNUSED(rd);
}
/* Record math.atan2. */
static void LJ_FASTCALL recff_math_atan2(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
TRef tr2 = lj_ir_tonum(J, J->base[1]);
J->base[0] = emitir(IRTN(IR_ATAN2), tr, tr2);
UNUSED(rd);
}
/* Record math.ldexp. */
static void LJ_FASTCALL recff_math_ldexp(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
#if LJ_TARGET_X86ORX64
TRef tr2 = lj_ir_tonum(J, J->base[1]);
#else
TRef tr2 = lj_opt_narrow_toint(J, J->base[1]);
#endif
J->base[0] = emitir(IRTN(IR_LDEXP), tr, tr2);
UNUSED(rd);
}
/* Record math.asin, math.acos, math.atan. */
static void LJ_FASTCALL recff_math_atrig(jit_State *J, RecordFFData *rd)
{
TRef y = lj_ir_tonum(J, J->base[0]);
TRef x = lj_ir_knum_one(J);
uint32_t ffid = rd->data;
if (ffid != FF_math_atan) {
TRef tmp = emitir(IRTN(IR_MUL), y, y);
tmp = emitir(IRTN(IR_SUB), x, tmp);
tmp = emitir(IRTN(IR_FPMATH), tmp, IRFPM_SQRT);
if (ffid == FF_math_asin) { x = tmp; } else { x = y; y = tmp; }
}
J->base[0] = emitir(IRTN(IR_ATAN2), y, x);
}
static void LJ_FASTCALL recff_math_htrig(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
J->base[0] = emitir(IRTN(IR_CALLN), tr, rd->data);
}
static void LJ_FASTCALL recff_math_modf(jit_State *J, RecordFFData *rd)
{
TRef tr = J->base[0];
if (tref_isinteger(tr)) {
J->base[0] = tr;
J->base[1] = lj_ir_kint(J, 0);
} else {
TRef trt;
tr = lj_ir_tonum(J, tr);
trt = emitir(IRTN(IR_FPMATH), tr, IRFPM_TRUNC);
J->base[0] = trt;
J->base[1] = emitir(IRTN(IR_SUB), tr, trt);
}
rd->nres = 2;
}
static void LJ_FASTCALL recff_math_degrad(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
TRef trm = lj_ir_knum(J, numV(&J->fn->c.upvalue[0]));
J->base[0] = emitir(IRTN(IR_MUL), tr, trm);
UNUSED(rd);
}
static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonum(J, J->base[0]);
if (!tref_isnumber_str(J->base[1]))
lj_trace_err(J, LJ_TRERR_BADTYPE);
J->base[0] = lj_opt_narrow_pow(J, tr, J->base[1], &rd->argv[1]);
UNUSED(rd);
}
static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_ir_tonumber(J, J->base[0]);
uint32_t op = rd->data;
BCReg i;
for (i = 1; J->base[i] != 0; i++) {
TRef tr2 = lj_ir_tonumber(J, J->base[i]);
IRType t = IRT_INT;
if (!(tref_isinteger(tr) && tref_isinteger(tr2))) {
if (tref_isinteger(tr)) tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
if (tref_isinteger(tr2)) tr2 = emitir(IRTN(IR_CONV), tr2, IRCONV_NUM_INT);
t = IRT_NUM;
}
tr = emitir(IRT(op, t), tr, tr2);
}
J->base[0] = tr;
}
static void LJ_FASTCALL recff_math_random(jit_State *J, RecordFFData *rd)
{
GCudata *ud = udataV(&J->fn->c.upvalue[0]);
TRef tr, one;
lj_ir_kgc(J, obj2gco(ud), IRT_UDATA); /* Prevent collection. */
tr = lj_ir_call(J, IRCALL_lj_math_random_step, lj_ir_kptr(J, uddata(ud)));
one = lj_ir_knum_one(J);
tr = emitir(IRTN(IR_SUB), tr, one);
if (J->base[0]) {
TRef tr1 = lj_ir_tonum(J, J->base[0]);
if (J->base[1]) { /* d = floor(d*(r2-r1+1.0)) + r1 */
TRef tr2 = lj_ir_tonum(J, J->base[1]);
tr2 = emitir(IRTN(IR_SUB), tr2, tr1);
tr2 = emitir(IRTN(IR_ADD), tr2, one);
tr = emitir(IRTN(IR_MUL), tr, tr2);
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_FLOOR);
tr = emitir(IRTN(IR_ADD), tr, tr1);
} else { /* d = floor(d*r1) + 1.0 */
tr = emitir(IRTN(IR_MUL), tr, tr1);
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_FLOOR);
tr = emitir(IRTN(IR_ADD), tr, one);
}
}
J->base[0] = tr;
UNUSED(rd);
}
/* -- Bit library fast functions ------------------------------------------ */
/* Record unary bit.tobit, bit.bnot, bit.bswap. */
static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
J->base[0] = (rd->data == IR_TOBIT) ? tr : emitir(IRTI(rd->data), tr, 0);
}
/* Record N-ary bit.band, bit.bor, bit.bxor. */
static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
uint32_t op = rd->data;
BCReg i;
for (i = 1; J->base[i] != 0; i++)
tr = emitir(IRTI(op), tr, lj_opt_narrow_tobit(J, J->base[i]));
J->base[0] = tr;
}
/* Record bit shifts. */
static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd)
{
TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
TRef tsh = lj_opt_narrow_tobit(J, J->base[1]);
IROp op = (IROp)rd->data;
if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
!tref_isk(tsh))
tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31));
#ifdef LJ_TARGET_UNIFYROT
if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
tsh = emitir(IRTI(IR_NEG), tsh, tsh);
}
#endif
J->base[0] = emitir(IRTI(op), tr, tsh);
}
/* -- String library fast functions --------------------------------------- */
static void LJ_FASTCALL recff_string_len(jit_State *J, RecordFFData *rd)
{
J->base[0] = emitir(IRTI(IR_FLOAD), lj_ir_tostr(J, J->base[0]), IRFL_STR_LEN);
UNUSED(rd);
}
/* Handle string.byte (rd->data = 0) and string.sub (rd->data = 1). */
static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd)
{
TRef trstr = lj_ir_tostr(J, J->base[0]);
TRef trlen = emitir(IRTI(IR_FLOAD), trstr, IRFL_STR_LEN);
TRef tr0 = lj_ir_kint(J, 0);
TRef trstart, trend;
GCstr *str = argv2str(J, &rd->argv[0]);
int32_t start, end;
if (rd->data) { /* string.sub(str, start [,end]) */
start = argv2int(J, &rd->argv[1]);
trstart = lj_opt_narrow_toint(J, J->base[1]);
trend = J->base[2];
if (tref_isnil(trend)) {
trend = lj_ir_kint(J, -1);
end = -1;
} else {
trend = lj_opt_narrow_toint(J, trend);
end = argv2int(J, &rd->argv[2]);
}
} else { /* string.byte(str, [,start [,end]]) */
if (J->base[1]) {
start = argv2int(J, &rd->argv[1]);
trstart = lj_opt_narrow_toint(J, J->base[1]);
trend = J->base[2];
if (tref_isnil(trend)) {
trend = trstart;
end = start;
} else {
trend = lj_opt_narrow_toint(J, trend);
end = argv2int(J, &rd->argv[2]);
}
} else {
trend = trstart = lj_ir_kint(J, 1);
end = start = 1;
}
}
if (end < 0) {
emitir(IRTGI(IR_LT), trend, tr0);
trend = emitir(IRTI(IR_ADD), emitir(IRTI(IR_ADD), trlen, trend),
lj_ir_kint(J, 1));
end = end+(int32_t)str->len+1;
} else if ((MSize)end <= str->len) {
emitir(IRTGI(IR_ULE), trend, trlen);
} else {
emitir(IRTGI(IR_GT), trend, trlen);
end = (int32_t)str->len;
trend = trlen;
}
if (start < 0) {
emitir(IRTGI(IR_LT), trstart, tr0);
trstart = emitir(IRTI(IR_ADD), trlen, trstart);
start = start+(int32_t)str->len;
emitir(start < 0 ? IRTGI(IR_LT) : IRTGI(IR_GE), trstart, tr0);
if (start < 0) {
trstart = tr0;
start = 0;
}
} else {
if (start == 0) {
emitir(IRTGI(IR_EQ), trstart, tr0);
trstart = tr0;
} else {
trstart = emitir(IRTI(IR_ADD), trstart, lj_ir_kint(J, -1));
emitir(IRTGI(IR_GE), trstart, tr0);
start--;
}
}
if (rd->data) { /* Return string.sub result. */
if (end - start >= 0) {
/* Also handle empty range here, to avoid extra traces. */
TRef trptr, trslen = emitir(IRTI(IR_SUB), trend, trstart);
emitir(IRTGI(IR_GE), trslen, tr0);
trptr = emitir(IRT(IR_STRREF, IRT_P32), trstr, trstart);
J->base[0] = emitir(IRT(IR_SNEW, IRT_STR), trptr, trslen);
} else { /* Range underflow: return empty string. */
emitir(IRTGI(IR_LT), trend, trstart);
J->base[0] = lj_ir_kstr(J, lj_str_new(J->L, strdata(str), 0));
}
} else { /* Return string.byte result(s). */
ptrdiff_t i, len = end - start;
if (len > 0) {
TRef trslen = emitir(IRTI(IR_SUB), trend, trstart);
emitir(IRTGI(IR_EQ), trslen, lj_ir_kint(J, (int32_t)len));
if (J->baseslot + len > LJ_MAX_JSLOTS)
lj_trace_err_info(J, LJ_TRERR_STACKOV);
rd->nres = len;
for (i = 0; i < len; i++) {
TRef tmp = emitir(IRTI(IR_ADD), trstart, lj_ir_kint(J, (int32_t)i));
tmp = emitir(IRT(IR_STRREF, IRT_P32), trstr, tmp);
J->base[i] = emitir(IRT(IR_XLOAD, IRT_U8), tmp, IRXLOAD_READONLY);
}
} else { /* Empty range or range underflow: return no results. */
emitir(IRTGI(IR_LE), trend, trstart);
rd->nres = 0;
}
}
}
/* -- Table library fast functions ---------------------------------------- */
static void LJ_FASTCALL recff_table_getn(jit_State *J, RecordFFData *rd)
{
if (tref_istab(J->base[0]))
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_len, J->base[0]);
/* else: Interpreter will throw. */
UNUSED(rd);
}
static void LJ_FASTCALL recff_table_remove(jit_State *J, RecordFFData *rd)
{
TRef tab = J->base[0];
rd->nres = 0;
if (tref_istab(tab)) {
if (!J->base[1] || tref_isnil(J->base[1])) { /* Simple pop: t[#t] = nil */
TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, tab);
GCtab *t = tabV(&rd->argv[0]);
MSize len = lj_tab_len(t);
emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
if (len) {
RecordIndex ix;
ix.tab = tab;
ix.key = trlen;
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, len);
ix.idxchain = 0;
if (results_wanted(J) != 0) { /* Specialize load only if needed. */
ix.val = 0;
J->base[0] = lj_record_idx(J, &ix); /* Load previous value. */
rd->nres = 1;
/* Assumes ix.key/ix.tab is not modified for raw lj_record_idx(). */
}
ix.val = TREF_NIL;
lj_record_idx(J, &ix); /* Remove value. */
}
} else { /* Complex case: remove in the middle. */
recff_nyiu(J);
}
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
{
RecordIndex ix;
ix.tab = J->base[0];
ix.val = J->base[1];
rd->nres = 0;
if (tref_istab(ix.tab) && ix.val) {
if (!J->base[2]) { /* Simple push: t[#t+1] = v */
TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, ix.tab);
GCtab *t = tabV(&rd->argv[0]);
ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, lj_tab_len(t) + 1);
ix.idxchain = 0;
lj_record_idx(J, &ix); /* Set new value. */
} else { /* Complex case: insert in the middle. */
recff_nyiu(J);
}
} /* else: Interpreter will throw. */
}
/* -- I/O library fast functions ------------------------------------------ */
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
** no need to encode the alternate cases for any of the guards.
*/
static TRef recff_io_fp(jit_State *J, TRef *udp, int32_t id)
{
TRef tr, ud, fp;
if (id) { /* io.func() */
tr = lj_ir_kptr(J, &J2G(J)->gcroot[id]);
ud = emitir(IRT(IR_XLOAD, IRT_UDATA), tr, 0);
} else { /* fp:method() */
ud = J->base[0];
if (!tref_isudata(ud))
lj_trace_err(J, LJ_TRERR_BADTYPE);
tr = emitir(IRT(IR_FLOAD, IRT_U8), ud, IRFL_UDATA_UDTYPE);
emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE));
}
*udp = ud;
fp = emitir(IRT(IR_FLOAD, IRT_PTR), ud, IRFL_UDATA_FILE);
emitir(IRTG(IR_NE, IRT_PTR), fp, lj_ir_knull(J, IRT_PTR));
return fp;
}
static void LJ_FASTCALL recff_io_write(jit_State *J, RecordFFData *rd)
{
TRef ud, fp = recff_io_fp(J, &ud, rd->data);
TRef zero = lj_ir_kint(J, 0);
TRef one = lj_ir_kint(J, 1);
ptrdiff_t i = rd->data == 0 ? 1 : 0;
for (; J->base[i]; i++) {
TRef str = lj_ir_tostr(J, J->base[i]);
TRef buf = emitir(IRT(IR_STRREF, IRT_P32), str, zero);
TRef len = emitir(IRTI(IR_FLOAD), str, IRFL_STR_LEN);
if (tref_isk(len) && IR(tref_ref(len))->i == 1) {
TRef tr = emitir(IRT(IR_XLOAD, IRT_U8), buf, IRXLOAD_READONLY);
tr = lj_ir_call(J, IRCALL_fputc, tr, fp);
if (results_wanted(J) != 0) /* Check result only if not ignored. */
emitir(IRTGI(IR_NE), tr, lj_ir_kint(J, -1));
} else {
TRef tr = lj_ir_call(J, IRCALL_fwrite, buf, one, len, fp);
if (results_wanted(J) != 0) /* Check result only if not ignored. */
emitir(IRTGI(IR_EQ), tr, len);
}
}
J->base[0] = LJ_52 ? ud : TREF_TRUE;
}
static void LJ_FASTCALL recff_io_flush(jit_State *J, RecordFFData *rd)
{
TRef ud, fp = recff_io_fp(J, &ud, rd->data);
TRef tr = lj_ir_call(J, IRCALL_fflush, fp);
if (results_wanted(J) != 0) /* Check result only if not ignored. */
emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
J->base[0] = TREF_TRUE;
}
/* -- Record calls to fast functions -------------------------------------- */
#include "lj_recdef.h"
static uint32_t recdef_lookup(GCfunc *fn)
{
if (fn->c.ffid < sizeof(recff_idmap)/sizeof(recff_idmap[0]))
return recff_idmap[fn->c.ffid];
else
return 0;
}
/* Record entry to a fast function or C function. */
void lj_ffrecord_func(jit_State *J)
{
RecordFFData rd;
uint32_t m = recdef_lookup(J->fn);
rd.data = m & 0xff;
rd.nres = 1; /* Default is one result. */
rd.argv = J->L->base;
J->base[J->maxslot] = 0; /* Mark end of arguments. */
(recff_func[m >> 8])(J, &rd); /* Call recff_* handler. */
if (rd.nres >= 0) {
if (J->postproc == LJ_POST_NONE) J->postproc = LJ_POST_FFRETRY;
lj_record_ret(J, 0, rd.nres);
}
}
#undef IR
#undef emitir
#endif
-183
View File
@@ -1,183 +0,0 @@
/*
** Stack frames.
** Copyright (C) 2005-2013 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 callee function slot (callee base-1). */
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. */
#define frame_gc(f) (gcref((f)->fr.func))
#define frame_func(f) (&frame_gc(f)->fn)
#define frame_ftsz(f) ((f)->fr.tp.ftsz)
#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_pc(f) (mref((f)->fr.tp.pcr, const BCIns))
#define frame_contpc(f) (frame_pc((f)-1))
#if 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_delta(f) (frame_ftsz(f) >> 3)
#define frame_sized(f) (frame_ftsz(f) & ~FRAME_TYPEP)
#define frame_prevl(f) ((f) - (1+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. */
#define setframe_pc(f, pc) (setmref((f)->fr.tp.pcr, (pc)))
#define setframe_ftsz(f, sz) ((f)->fr.tp.ftsz = (sz))
#define setframe_gc(f, p) (setgcref((f)->fr.func, (p)))
/* -- 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
#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
#elif LJ_TARGET_X64
#if LJ_ABI_WIN
#define CFRAME_OFS_PREV (13*8)
#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)
#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)
#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)
#define CFRAME_SIZE (10*8)
#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_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_PPC64
#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_PPCSPE
#define CFRAME_OFS_ERRF 28
#define CFRAME_OFS_NRES 24
#define CFRAME_OFS_PREV 20
#define CFRAME_OFS_L 16
#define CFRAME_OFS_PC 12
#define CFRAME_OFS_MULTRES 8
#define CFRAME_SIZE 184
#define CFRAME_SHIFT_MULTRES 3
#elif LJ_TARGET_MIPS
#define CFRAME_OFS_ERRF 124
#define CFRAME_OFS_NRES 120
#define CFRAME_OFS_PREV 116
#define CFRAME_OFS_L 112
#define CFRAME_OFS_PC 20
#define CFRAME_OFS_MULTRES 16
#define CFRAME_SIZE 112
#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
-271
View File
@@ -1,271 +0,0 @@
/*
** IR CALL* instruction definitions.
** Copyright (C) 2005-2013 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) /* Extract # 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_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. */
/* 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
#define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS)
#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 ARG1_FP 2 /* Treat as 2 32 bit arguments. */
#else
#define ARG1_FP 1
#endif
#if LJ_32
#define ARG2_64 4 /* Treat as 4 32 bit arguments. */
#else
#define ARG2_64 2
#endif
/* Function definitions for CALL* instructions. */
#define IRCALLDEF(_) \
_(ANY, lj_str_cmp, 2, FN, INT, CCI_NOFPRCLOBBER) \
_(ANY, lj_str_new, 3, S, STR, CCI_L) \
_(ANY, lj_strscan_num, 2, FN, INT, 0) \
_(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \
_(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \
_(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \
_(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \
_(ANY, lj_tab_newkey, 3, S, P32, 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, P32, CCI_L) \
_(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_NOFPRCLOBBER) \
_(ANY, lj_vm_modi, 2, FN, INT, 0) \
_(ANY, sinh, ARG1_FP, N, NUM, 0) \
_(ANY, cosh, ARG1_FP, N, NUM, 0) \
_(ANY, tanh, ARG1_FP, N, NUM, 0) \
_(ANY, fputc, 2, S, INT, 0) \
_(ANY, fwrite, 4, S, INT, 0) \
_(ANY, fflush, 1, S, INT, 0) \
/* ORDER FPM */ \
_(FPMATH, lj_vm_floor, ARG1_FP, N, NUM, 0) \
_(FPMATH, lj_vm_ceil, ARG1_FP, N, NUM, 0) \
_(FPMATH, lj_vm_trunc, ARG1_FP, N, NUM, 0) \
_(FPMATH, sqrt, ARG1_FP, N, NUM, 0) \
_(FPMATH, exp, ARG1_FP, N, NUM, 0) \
_(FPMATH, lj_vm_exp2, ARG1_FP, N, NUM, 0) \
_(FPMATH, log, ARG1_FP, N, NUM, 0) \
_(FPMATH, lj_vm_log2, ARG1_FP, N, NUM, 0) \
_(FPMATH, log10, ARG1_FP, N, NUM, 0) \
_(FPMATH, sin, ARG1_FP, N, NUM, 0) \
_(FPMATH, cos, ARG1_FP, N, NUM, 0) \
_(FPMATH, tan, ARG1_FP, N, NUM, 0) \
_(FPMATH, lj_vm_powi, ARG1_FP+1, N, NUM, 0) \
_(FPMATH, pow, ARG1_FP*2, N, NUM, 0) \
_(FPMATH, atan2, ARG1_FP*2, N, NUM, 0) \
_(FPMATH, ldexp, ARG1_FP+1, N, NUM, 0) \
_(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_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, 2, N, NUM, 0) \
_(FP64_FFI, fp64_ul2d, 2, N, NUM, 0) \
_(FP64_FFI, fp64_l2f, 2, N, FLOAT, 0) \
_(FP64_FFI, fp64_ul2f, 2, N, FLOAT, 0) \
_(FP64_FFI, fp64_d2l, ARG1_FP, N, I64, 0) \
_(FP64_FFI, fp64_d2ul, ARG1_FP, N, U64, 0) \
_(FP64_FFI, fp64_f2l, 1, N, I64, 0) \
_(FP64_FFI, fp64_f2ul, 1, N, U64, 0) \
_(FFI, lj_carith_divi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
_(FFI, lj_carith_divu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
_(FFI, lj_carith_modi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
_(FFI, lj_carith_modu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
_(FFI, lj_carith_powi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
_(FFI, lj_carith_powu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
_(FFI, lj_cdata_setfin, 2, FN, P32, 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, ARG2_64, N, I64, 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
#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
#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
-481
View File
@@ -1,481 +0,0 @@
/*
** Lexical analyzer.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lj_lex_c
#define LUA_CORE
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#if LJ_HASFFI
#include "lj_tab.h"
#include "lj_ctype.h"
#include "lj_cdata.h"
#include "lualib.h"
#endif
#include "lj_state.h"
#include "lj_lex.h"
#include "lj_parse.h"
#include "lj_char.h"
#include "lj_strscan.h"
/* Lua lexer token names. */
static const char *const tokennames[] = {
#define TKSTR1(name) #name,
#define TKSTR2(name, sym) #sym,
TKDEF(TKSTR1, TKSTR2)
#undef TKSTR1
#undef TKSTR2
NULL
};
/* -- Buffer handling ----------------------------------------------------- */
#define char2int(c) ((int)(uint8_t)(c))
#define next(ls) \
(ls->current = (ls->n--) > 0 ? char2int(*ls->p++) : fillbuf(ls))
#define save_and_next(ls) (save(ls, ls->current), next(ls))
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
#define END_OF_STREAM (-1)
static int fillbuf(LexState *ls)
{
size_t sz;
const char *buf = ls->rfunc(ls->L, ls->rdata, &sz);
if (buf == NULL || sz == 0) return END_OF_STREAM;
ls->n = (MSize)sz - 1;
ls->p = buf;
return char2int(*(ls->p++));
}
static LJ_NOINLINE void save_grow(LexState *ls, int c)
{
MSize newsize;
if (ls->sb.sz >= LJ_MAX_STR/2)
lj_lex_error(ls, 0, LJ_ERR_XELEM);
newsize = ls->sb.sz * 2;
lj_str_resizebuf(ls->L, &ls->sb, newsize);
ls->sb.buf[ls->sb.n++] = (char)c;
}
static LJ_AINLINE void save(LexState *ls, int c)
{
if (LJ_UNLIKELY(ls->sb.n + 1 > ls->sb.sz))
save_grow(ls, c);
else
ls->sb.buf[ls->sb.n++] = (char)c;
}
static void inclinenumber(LexState *ls)
{
int old = ls->current;
lua_assert(currIsNewline(ls));
next(ls); /* skip `\n' or `\r' */
if (currIsNewline(ls) && ls->current != old)
next(ls); /* skip `\n\r' or `\r\n' */
if (++ls->linenumber >= LJ_MAX_LINE)
lj_lex_error(ls, ls->token, LJ_ERR_XLINES);
}
/* -- Scanner for terminals ----------------------------------------------- */
/* Parse a number literal. */
static void lex_number(LexState *ls, TValue *tv)
{
StrScanFmt fmt;
int c, xp = 'e';
lua_assert(lj_char_isdigit(ls->current));
if ((c = ls->current) == '0') {
save_and_next(ls);
if ((ls->current | 0x20) == 'x') xp = 'p';
}
while (lj_char_isident(ls->current) || ls->current == '.' ||
((ls->current == '-' || ls->current == '+') && (c | 0x20) == xp)) {
c = ls->current;
save_and_next(ls);
}
save(ls, '\0');
fmt = lj_strscan_scan((const uint8_t *)ls->sb.buf, tv,
(LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
(LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
if (LJ_DUALNUM && fmt == STRSCAN_INT) {
setitype(tv, LJ_TISNUM);
} else if (fmt == STRSCAN_NUM) {
/* Already in correct format. */
#if LJ_HASFFI
} else if (fmt != STRSCAN_ERROR) {
lua_State *L = ls->L;
GCcdata *cd;
lua_assert(fmt == STRSCAN_I64 || fmt == STRSCAN_U64 || fmt == STRSCAN_IMAG);
if (!ctype_ctsG(G(L))) {
ptrdiff_t oldtop = savestack(L, L->top);
luaopen_ffi(L); /* Load FFI library on-demand. */
L->top = restorestack(L, oldtop);
}
if (fmt == STRSCAN_IMAG) {
cd = lj_cdata_new_(L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
((double *)cdataptr(cd))[0] = 0;
((double *)cdataptr(cd))[1] = numV(tv);
} else {
cd = lj_cdata_new_(L, fmt==STRSCAN_I64 ? CTID_INT64 : CTID_UINT64, 8);
*(uint64_t *)cdataptr(cd) = tv->u64;
}
lj_parse_keepcdata(ls, tv, cd);
#endif
} else {
lua_assert(fmt == STRSCAN_ERROR);
lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
}
}
static int skip_sep(LexState *ls)
{
int count = 0;
int s = ls->current;
lua_assert(s == '[' || s == ']');
save_and_next(ls);
while (ls->current == '=') {
save_and_next(ls);
count++;
}
return (ls->current == s) ? count : (-count) - 1;
}
static void read_long_string(LexState *ls, TValue *tv, int sep)
{
save_and_next(ls); /* skip 2nd `[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
for (;;) {
switch (ls->current) {
case END_OF_STREAM:
lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM);
break;
case ']':
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `]' */
goto endloop;
}
break;
case '\n':
case '\r':
save(ls, '\n');
inclinenumber(ls);
if (!tv) lj_str_resetbuf(&ls->sb); /* avoid wasting space */
break;
default:
if (tv) save_and_next(ls);
else next(ls);
break;
}
} endloop:
if (tv) {
GCstr *str = lj_parse_keepstr(ls, ls->sb.buf + (2 + (MSize)sep),
ls->sb.n - 2*(2 + (MSize)sep));
setstrV(ls->L, tv, str);
}
}
static void read_string(LexState *ls, int delim, TValue *tv)
{
save_and_next(ls);
while (ls->current != delim) {
switch (ls->current) {
case END_OF_STREAM:
lj_lex_error(ls, TK_eof, LJ_ERR_XSTR);
continue;
case '\n':
case '\r':
lj_lex_error(ls, TK_string, LJ_ERR_XSTR);
continue;
case '\\': {
int c = next(ls); /* Skip the '\\'. */
switch (c) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case 'x': /* Hexadecimal escape '\xXX'. */
c = (next(ls) & 15u) << 4;
if (!lj_char_isdigit(ls->current)) {
if (!lj_char_isxdigit(ls->current)) goto err_xesc;
c += 9 << 4;
}
c += (next(ls) & 15u);
if (!lj_char_isdigit(ls->current)) {
if (!lj_char_isxdigit(ls->current)) goto err_xesc;
c += 9;
}
break;
case 'z': /* Skip whitespace. */
next(ls);
while (lj_char_isspace(ls->current))
if (currIsNewline(ls)) inclinenumber(ls); else next(ls);
continue;
case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue;
case '\\': case '\"': case '\'': break;
case END_OF_STREAM: continue;
default:
if (!lj_char_isdigit(c))
goto err_xesc;
c -= '0'; /* Decimal escape '\ddd'. */
if (lj_char_isdigit(next(ls))) {
c = c*10 + (ls->current - '0');
if (lj_char_isdigit(next(ls))) {
c = c*10 + (ls->current - '0');
if (c > 255) {
err_xesc:
lj_lex_error(ls, TK_string, LJ_ERR_XESC);
}
next(ls);
}
}
save(ls, c);
continue;
}
save(ls, c);
next(ls);
continue;
}
default:
save_and_next(ls);
break;
}
}
save_and_next(ls); /* skip delimiter */
setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2));
}
/* -- Main lexical scanner ------------------------------------------------ */
static int llex(LexState *ls, TValue *tv)
{
lj_str_resetbuf(&ls->sb);
for (;;) {
if (lj_char_isident(ls->current)) {
GCstr *s;
if (lj_char_isdigit(ls->current)) { /* Numeric literal. */
lex_number(ls, tv);
return TK_number;
}
/* Identifier or reserved word. */
do {
save_and_next(ls);
} while (lj_char_isident(ls->current));
s = lj_parse_keepstr(ls, ls->sb.buf, ls->sb.n);
setstrV(ls->L, tv, s);
if (s->reserved > 0) /* Reserved word? */
return TK_OFS + s->reserved;
return TK_name;
}
switch (ls->current) {
case '\n':
case '\r':
inclinenumber(ls);
continue;
case ' ':
case '\t':
case '\v':
case '\f':
next(ls);
continue;
case '-':
next(ls);
if (ls->current != '-') return '-';
/* else is a comment */
next(ls);
if (ls->current == '[') {
int sep = skip_sep(ls);
lj_str_resetbuf(&ls->sb); /* `skip_sep' may dirty the buffer */
if (sep >= 0) {
read_long_string(ls, NULL, sep); /* long comment */
lj_str_resetbuf(&ls->sb);
continue;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls->current != END_OF_STREAM)
next(ls);
continue;
case '[': {
int sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, tv, sep);
return TK_string;
} else if (sep == -1) {
return '[';
} else {
lj_lex_error(ls, TK_string, LJ_ERR_XLDELIM);
continue;
}
}
case '=':
next(ls);
if (ls->current != '=') return '='; else { next(ls); return TK_eq; }
case '<':
next(ls);
if (ls->current != '=') return '<'; else { next(ls); return TK_le; }
case '>':
next(ls);
if (ls->current != '=') return '>'; else { next(ls); return TK_ge; }
case '~':
next(ls);
if (ls->current != '=') return '~'; else { next(ls); return TK_ne; }
case ':':
next(ls);
if (ls->current != ':') return ':'; else { next(ls); return TK_label; }
case '"':
case '\'':
read_string(ls, ls->current, tv);
return TK_string;
case '.':
save_and_next(ls);
if (ls->current == '.') {
next(ls);
if (ls->current == '.') {
next(ls);
return TK_dots; /* ... */
}
return TK_concat; /* .. */
} else if (!lj_char_isdigit(ls->current)) {
return '.';
} else {
lex_number(ls, tv);
return TK_number;
}
case END_OF_STREAM:
return TK_eof;
default: {
int c = ls->current;
next(ls);
return c; /* Single-char tokens (+ - / ...). */
}
}
}
}
/* -- Lexer API ----------------------------------------------------------- */
/* Setup lexer state. */
int lj_lex_setup(lua_State *L, LexState *ls)
{
int header = 0;
ls->L = L;
ls->fs = NULL;
ls->n = 0;
ls->p = NULL;
ls->vstack = NULL;
ls->sizevstack = 0;
ls->vtop = 0;
ls->bcstack = NULL;
ls->sizebcstack = 0;
ls->lookahead = TK_eof; /* No look-ahead token. */
ls->linenumber = 1;
ls->lastline = 1;
lj_str_resizebuf(ls->L, &ls->sb, LJ_MIN_SBUF);
next(ls); /* Read-ahead first char. */
if (ls->current == 0xef && ls->n >= 2 && char2int(ls->p[0]) == 0xbb &&
char2int(ls->p[1]) == 0xbf) { /* Skip UTF-8 BOM (if buffered). */
ls->n -= 2;
ls->p += 2;
next(ls);
header = 1;
}
if (ls->current == '#') { /* Skip POSIX #! header line. */
do {
next(ls);
if (ls->current == END_OF_STREAM) return 0;
} while (!currIsNewline(ls));
inclinenumber(ls);
header = 1;
}
if (ls->current == LUA_SIGNATURE[0]) { /* Bytecode dump. */
if (header) {
/*
** Loading bytecode with an extra header is disabled for security
** reasons. This may circumvent the usual check for bytecode vs.
** Lua code by looking at the first char. Since this is a potential
** security violation no attempt is made to echo the chunkname either.
*/
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_BCBAD));
lj_err_throw(L, LUA_ERRSYNTAX);
}
return 1;
}
return 0;
}
/* Cleanup lexer state. */
void lj_lex_cleanup(lua_State *L, LexState *ls)
{
global_State *g = G(L);
lj_mem_freevec(g, ls->bcstack, ls->sizebcstack, BCInsLine);
lj_mem_freevec(g, ls->vstack, ls->sizevstack, VarInfo);
lj_str_freebuf(g, &ls->sb);
}
void lj_lex_next(LexState *ls)
{
ls->lastline = ls->linenumber;
if (LJ_LIKELY(ls->lookahead == TK_eof)) { /* No lookahead token? */
ls->token = llex(ls, &ls->tokenval); /* Get next token. */
} else { /* Otherwise return lookahead token. */
ls->token = ls->lookahead;
ls->lookahead = TK_eof;
ls->tokenval = ls->lookaheadval;
}
}
LexToken lj_lex_lookahead(LexState *ls)
{
lua_assert(ls->lookahead == TK_eof);
ls->lookahead = llex(ls, &ls->lookaheadval);
return ls->lookahead;
}
const char *lj_lex_token2str(LexState *ls, LexToken token)
{
if (token > TK_OFS)
return tokennames[token-TK_OFS-1];
else if (!lj_char_iscntrl(token))
return lj_str_pushf(ls->L, "%c", token);
else
return lj_str_pushf(ls->L, "char(%d)", token);
}
void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...)
{
const char *tok;
va_list argp;
if (token == 0) {
tok = NULL;
} else if (token == TK_name || token == TK_string || token == TK_number) {
save(ls, '\0');
tok = ls->sb.buf;
} else {
tok = lj_lex_token2str(ls, token);
}
va_start(argp, em);
lj_err_lex(ls->L, ls->chunkname, tok, ls->linenumber, em, argp);
va_end(argp);
}
void lj_lex_init(lua_State *L)
{
uint32_t i;
for (i = 0; i < TK_RESERVED; i++) {
GCstr *s = lj_str_newz(L, tokennames[i]);
fixstring(s); /* Reserved words are never collected. */
s->reserved = (uint8_t)(i+1);
}
}
-35
View File
@@ -1,35 +0,0 @@
/*
** Miscellaneous object handling.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/
#define lj_obj_c
#define LUA_CORE
#include "lj_obj.h"
/* Object type names. */
LJ_DATADEF const char *const lj_obj_typename[] = { /* ORDER LUA_T */
"no value", "nil", "boolean", "userdata", "number", "string",
"table", "function", "userdata", "thread", "proto", "cdata"
};
LJ_DATADEF const char *const lj_obj_itypename[] = { /* ORDER LJ_T */
"nil", "boolean", "boolean", "userdata", "string", "upval", "thread",
"proto", "function", "trace", "cdata", "table", "userdata", "number"
};
/* Compare two objects without calling metamethods. */
int lj_obj_equal(cTValue *o1, cTValue *o2)
{
if (itype(o1) == itype(o2)) {
if (tvispri(o1))
return 1;
if (!tvisnum(o1))
return gcrefeq(o1->gcr, o2->gcr);
} else if (!tvisnumber(o1) || !tvisnumber(o2)) {
return 0;
}
return numberVnum(o1) == numberVnum(o2);
}
-339
View File
@@ -1,339 +0,0 @@
/*
** String handling.
** Copyright (C) 2005-2013 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
*/
#include <stdio.h>
#define lj_str_c
#define LUA_CORE
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#include "lj_state.h"
#include "lj_char.h"
/* -- String interning ---------------------------------------------------- */
/* Ordered compare of strings. Assumes string data is 4-byte aligned. */
int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
{
MSize i, n = a->len > b->len ? b->len : a->len;
for (i = 0; i < n; i += 4) {
/* Note: innocuous access up to end of string + 3. */
uint32_t va = *(const uint32_t *)(strdata(a)+i);
uint32_t vb = *(const uint32_t *)(strdata(b)+i);
if (va != vb) {
#if LJ_LE
va = lj_bswap(va); vb = lj_bswap(vb);
#endif
i -= n;
if ((int32_t)i >= -3) {
va >>= 32+(i<<3); vb >>= 32+(i<<3);
if (va == vb) break;
}
return va < vb ? -1 : 1;
}
}
return (int32_t)(a->len - b->len);
}
/* Fast string data comparison. Caveat: unaligned access to 1st string! */
static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
{
MSize i = 0;
lua_assert(len > 0);
lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4);
do { /* Note: innocuous access up to end of string + 3. */
uint32_t v = lj_getu32(a+i) ^ *(const uint32_t *)(b+i);
if (v) {
i -= len;
#if LJ_LE
return (int32_t)i >= -3 ? (v << (32+(i<<3))) : 1;
#else
return (int32_t)i >= -3 ? (v >> (32+(i<<3))) : 1;
#endif
}
i += 4;
} while (i < len);
return 0;
}
/* Resize the string hash table (grow and shrink). */
void lj_str_resize(lua_State *L, MSize newmask)
{
global_State *g = G(L);
GCRef *newhash;
MSize i;
if (g->gc.state == GCSsweepstring || newmask >= LJ_MAX_STRTAB-1)
return; /* No resizing during GC traversal or if already too big. */
newhash = lj_mem_newvec(L, newmask+1, GCRef);
memset(newhash, 0, (newmask+1)*sizeof(GCRef));
for (i = g->strmask; i != ~(MSize)0; i--) { /* Rehash old table. */
GCobj *p = gcref(g->strhash[i]);
while (p) { /* Follow each hash chain and reinsert all strings. */
MSize h = gco2str(p)->hash & newmask;
GCobj *next = gcnext(p);
/* NOBARRIER: The string table is a GC root. */
setgcrefr(p->gch.nextgc, newhash[h]);
setgcref(newhash[h], p);
p = next;
}
}
lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef);
g->strmask = newmask;
g->strhash = newhash;
}
/* Intern a string and return string object. */
GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
{
global_State *g;
GCstr *s;
GCobj *o;
MSize len = (MSize)lenx;
MSize a, b, h = len;
if (lenx >= LJ_MAX_STR)
lj_err_msg(L, LJ_ERR_STROV);
g = G(L);
/* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
if (len >= 4) { /* Caveat: unaligned access! */
a = lj_getu32(str);
h ^= lj_getu32(str+len-4);
b = lj_getu32(str+(len>>1)-2);
h ^= b; h -= lj_rol(b, 14);
b += lj_getu32(str+(len>>2)-1);
} else if (len > 0) {
a = *(const uint8_t *)str;
h ^= *(const uint8_t *)(str+len-1);
b = *(const uint8_t *)(str+(len>>1));
h ^= b; h -= lj_rol(b, 14);
} else {
return &g->strempty;
}
a ^= h; a -= lj_rol(h, 11);
b ^= a; b -= lj_rol(a, 25);
h ^= b; h -= lj_rol(b, 16);
/* Check if the string has already been interned. */
o = gcref(g->strhash[h & g->strmask]);
if (LJ_LIKELY((((uintptr_t)str + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
while (o != NULL) {
GCstr *sx = gco2str(o);
if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
}
o = gcnext(o);
}
} else { /* Slow path: end of string is too close to a page boundary. */
while (o != NULL) {
GCstr *sx = gco2str(o);
if (sx->len == len && memcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
}
o = gcnext(o);
}
}
/* Nope, create a new string. */
s = lj_mem_newt(L, sizeof(GCstr)+len+1, GCstr);
newwhite(g, s);
s->gct = ~LJ_TSTR;
s->len = len;
s->hash = h;
s->reserved = 0;
memcpy(strdatawr(s), str, len);
strdatawr(s)[len] = '\0'; /* Zero-terminate string. */
/* Add it to string hash table. */
h &= g->strmask;
s->nextgc = g->strhash[h];
/* NOBARRIER: The string table is a GC root. */
setgcref(g->strhash[h], obj2gco(s));
if (g->strnum++ > g->strmask) /* Allow a 100% load factor. */
lj_str_resize(L, (g->strmask<<1)+1); /* Grow string table. */
return s; /* Return newly interned string. */
}
void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s)
{
g->strnum--;
lj_mem_free(g, s, sizestring(s));
}
/* -- Type conversions ---------------------------------------------------- */
/* Print number to buffer. Canonicalizes non-finite values. */
size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o)
{
if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) { /* Finite? */
lua_Number n = o->n;
#if __BIONIC__
if (tvismzero(o)) { s[0] = '-'; s[1] = '0'; return 2; }
#endif
return (size_t)lua_number2str(s, n);
} else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) {
s[0] = 'n'; s[1] = 'a'; s[2] = 'n'; return 3;
} else if ((o->u32.hi & 0x80000000) == 0) {
s[0] = 'i'; s[1] = 'n'; s[2] = 'f'; return 3;
} else {
s[0] = '-'; s[1] = 'i'; s[2] = 'n'; s[3] = 'f'; return 4;
}
}
/* Print integer to buffer. Returns pointer to start. */
char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k)
{
uint32_t u = (uint32_t)(k < 0 ? -k : k);
p += 1+10;
do { *--p = (char)('0' + u % 10); } while (u /= 10);
if (k < 0) *--p = '-';
return p;
}
/* Convert number to string. */
GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
{
char buf[LJ_STR_NUMBUF];
size_t len = lj_str_bufnum(buf, (TValue *)np);
return lj_str_new(L, buf, len);
}
/* Convert integer to string. */
GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k)
{
char s[1+10];
char *p = lj_str_bufint(s, k);
return lj_str_new(L, p, (size_t)(s+sizeof(s)-p));
}
GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
{
return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n);
}
/* -- String formatting --------------------------------------------------- */
static void addstr(lua_State *L, SBuf *sb, const char *str, MSize len)
{
char *p;
MSize i;
if (sb->n + len > sb->sz) {
MSize sz = sb->sz * 2;
while (sb->n + len > sz) sz = sz * 2;
lj_str_resizebuf(L, sb, sz);
}
p = sb->buf + sb->n;
sb->n += len;
for (i = 0; i < len; i++) p[i] = str[i];
}
static void addchar(lua_State *L, SBuf *sb, int c)
{
if (sb->n + 1 > sb->sz) {
MSize sz = sb->sz * 2;
lj_str_resizebuf(L, sb, sz);
}
sb->buf[sb->n++] = (char)c;
}
/* Push formatted message as a string object to Lua stack. va_list variant. */
const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
{
SBuf *sb = &G(L)->tmpbuf;
lj_str_needbuf(L, sb, (MSize)strlen(fmt));
lj_str_resetbuf(sb);
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
addstr(L, sb, fmt, (MSize)(e-fmt));
/* This function only handles %s, %c, %d, %f and %p formats. */
switch (e[1]) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
addstr(L, sb, s, (MSize)strlen(s));
break;
}
case 'c':
addchar(L, sb, va_arg(argp, int));
break;
case 'd': {
char buf[LJ_STR_INTBUF];
char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
break;
}
case 'f': {
char buf[LJ_STR_NUMBUF];
TValue tv;
MSize len;
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
len = (MSize)lj_str_bufnum(buf, &tv);
addstr(L, sb, buf, len);
break;
}
case 'p': {
#define FMTP_CHARS (2*sizeof(ptrdiff_t))
char buf[2+FMTP_CHARS];
ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
ptrdiff_t i, lasti = 2+FMTP_CHARS;
if (p == 0) {
addstr(L, sb, "NULL", 4);
break;
}
#if LJ_64
/* Shorten output for 64 bit pointers. */
lasti = 2+2*4+((p >> 32) ? 2+2*(lj_fls((uint32_t)(p >> 32))>>3) : 0);
#endif
buf[0] = '0';
buf[1] = 'x';
for (i = lasti-1; i >= 2; i--, p >>= 4)
buf[i] = "0123456789abcdef"[(p & 15)];
addstr(L, sb, buf, (MSize)lasti);
break;
}
case '%':
addchar(L, sb, '%');
break;
default:
addchar(L, sb, '%');
addchar(L, sb, e[1]);
break;
}
fmt = e+2;
}
addstr(L, sb, fmt, (MSize)strlen(fmt));
setstrV(L, L->top, lj_str_new(L, sb->buf, sb->n));
incr_top(L);
return strVdata(L->top - 1);
}
/* Push formatted message as a string object to Lua stack. Vararg variant. */
const char *lj_str_pushf(lua_State *L, const char *fmt, ...)
{
const char *msg;
va_list argp;
va_start(argp, fmt);
msg = lj_str_pushvf(L, fmt, argp);
va_end(argp);
return msg;
}
/* -- Buffer handling ----------------------------------------------------- */
char *lj_str_needbuf(lua_State *L, SBuf *sb, MSize sz)
{
if (sz > sb->sz) {
if (sz < LJ_MIN_SBUF) sz = LJ_MIN_SBUF;
lj_str_resizebuf(L, sb, sz);
}
return sb->buf;
}
-50
View File
@@ -1,50 +0,0 @@
/*
** String handling.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/
#ifndef _LJ_STR_H
#define _LJ_STR_H
#include <stdarg.h>
#include "lj_obj.h"
/* String interning. */
LJ_FUNC int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b);
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))
/* Type conversions. */
LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o);
LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k);
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o);
#define LJ_STR_INTBUF (1+10)
#define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR
/* String formatting. */
LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp);
LJ_FUNC const char *lj_str_pushf(lua_State *L, const char *fmt, ...)
#if defined(__GNUC__)
__attribute__ ((format (printf, 2, 3)))
#endif
;
/* Resizable string buffers. Struct definition in lj_obj.h. */
LJ_FUNC char *lj_str_needbuf(lua_State *L, SBuf *sb, MSize sz);
#define lj_str_initbuf(sb) ((sb)->buf = NULL, (sb)->sz = 0)
#define lj_str_resetbuf(sb) ((sb)->n = 0)
#define lj_str_resizebuf(L, sb, size) \
((sb)->buf = (char *)lj_mem_realloc(L, (sb)->buf, (sb)->sz, (size)), \
(sb)->sz = (size))
#define lj_str_freebuf(g, sb) lj_mem_free(g, (void *)(sb)->buf, (sb)->sz)
#endif
-140
View File
@@ -1,140 +0,0 @@
/*
** Math helper functions for assembler VM.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/
#define lj_vmmath_c
#define LUA_CORE
#include <errno.h>
#include <math.h>
#include "lj_obj.h"
#include "lj_ir.h"
#include "lj_vm.h"
/* -- Helper functions for generated machine code ------------------------- */
#if LJ_TARGET_X86ORX64
/* Wrapper functions to avoid linker issues on OSX. */
LJ_FUNCA double lj_vm_sinh(double x) { return sinh(x); }
LJ_FUNCA double lj_vm_cosh(double x) { return cosh(x); }
LJ_FUNCA double lj_vm_tanh(double x) { return tanh(x); }
#endif
#if !LJ_TARGET_X86ORX64
double lj_vm_foldarith(double x, double y, int op)
{
switch (op) {
case IR_ADD - IR_ADD: return x+y; break;
case IR_SUB - IR_ADD: return x-y; break;
case IR_MUL - IR_ADD: return x*y; break;
case IR_DIV - IR_ADD: return x/y; break;
case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break;
case IR_POW - IR_ADD: return pow(x, y); break;
case IR_NEG - IR_ADD: return -x; break;
case IR_ABS - IR_ADD: return fabs(x); break;
#if LJ_HASJIT
case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
case IR_MIN - IR_ADD: return x > y ? y : x; break;
case IR_MAX - IR_ADD: return x < y ? y : x; break;
#endif
default: return x;
}
}
#endif
#if LJ_HASJIT
#ifdef LUAJIT_NO_LOG2
double lj_vm_log2(double a)
{
return log(a) * 1.4426950408889634074;
}
#endif
#ifdef LUAJIT_NO_EXP2
double lj_vm_exp2(double a)
{
return exp(a * 0.6931471805599453);
}
#endif
#if !(LJ_TARGET_ARM || LJ_TARGET_PPC)
int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
{
uint32_t y, ua, ub;
lua_assert(b != 0); /* This must be checked before using this function. */
ua = a < 0 ? (uint32_t)-a : (uint32_t)a;
ub = b < 0 ? (uint32_t)-b : (uint32_t)b;
y = ua % ub;
if (y != 0 && (a^b) < 0) y = y - ub;
if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y;
return (int32_t)y;
}
#endif
#if !LJ_TARGET_X86ORX64
/* Unsigned x^k. */
static double lj_vm_powui(double x, uint32_t k)
{
double y;
lua_assert(k != 0);
for (; (k & 1) == 0; k >>= 1) x *= x;
y = x;
if ((k >>= 1) != 0) {
for (;;) {
x *= x;
if (k == 1) break;
if (k & 1) y *= x;
k >>= 1;
}
y *= x;
}
return y;
}
/* Signed x^k. */
double lj_vm_powi(double x, int32_t k)
{
if (k > 1)
return lj_vm_powui(x, (uint32_t)k);
else if (k == 1)
return x;
else if (k == 0)
return 1.0;
else
return 1.0 / lj_vm_powui(x, (uint32_t)-k);
}
/* Computes fpm(x) for extended math functions. */
double lj_vm_foldfpm(double x, int fpm)
{
switch (fpm) {
case IRFPM_FLOOR: return lj_vm_floor(x);
case IRFPM_CEIL: return lj_vm_ceil(x);
case IRFPM_TRUNC: return lj_vm_trunc(x);
case IRFPM_SQRT: return sqrt(x);
case IRFPM_EXP: return exp(x);
case IRFPM_EXP2: return lj_vm_exp2(x);
case IRFPM_LOG: return log(x);
case IRFPM_LOG2: return lj_vm_log2(x);
case IRFPM_LOG10: return log10(x);
case IRFPM_SIN: return sin(x);
case IRFPM_COS: return cos(x);
case IRFPM_TAN: return tan(x);
default: lua_assert(0);
}
return 0;
}
#endif
#if LJ_HASFFI
int lj_vm_errno(void)
{
return errno;
}
#endif
#endif
+56
View File
@@ -0,0 +1,56 @@
===============================================================================
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
Copyright (C) 2005-2015 Mike Pall. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
===============================================================================
[ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
Copyright (C) 1994-2012 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
[ LuaJIT includes code from dlmalloc, which has this license statement: ]
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
http://creativecommons.org/licenses/publicdomain
===============================================================================
+159
View File
@@ -0,0 +1,159 @@
##############################################################################
# LuaJIT top level Makefile for installation. Requires GNU Make.
#
# Please read doc/install.html before changing any variables!
#
# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
# Note: src/Makefile has many more configurable options.
#
# ##### This Makefile is NOT useful for Windows! #####
# For MSVC, please follow the instructions given in src/msvcbuild.bat.
# For MinGW and Cygwin, cd to src and run make with the Makefile there.
#
# Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
##############################################################################
MAJVER= 2
MINVER= 1
RELVER= 0
PREREL= -beta1
VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL)
ABIVER= 5.1
##############################################################################
#
# Change the installation path as needed. This automatically adjusts
# the paths in src/luaconf.h, too. Note: PREFIX must be an absolute path!
#
export PREFIX= /usr/local
export MULTILIB= lib
##############################################################################
DPREFIX= $(DESTDIR)$(PREFIX)
INSTALL_BIN= $(DPREFIX)/bin
INSTALL_LIB= $(DPREFIX)/$(MULTILIB)
INSTALL_SHARE= $(DPREFIX)/share
INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(VERSION)
INSTALL_JITLIB= $(INSTALL_LJLIBD)/jit
INSTALL_LMODD= $(INSTALL_SHARE)/lua
INSTALL_LMOD= $(INSTALL_LMODD)/$(ABIVER)
INSTALL_CMODD= $(INSTALL_LIB)/lua
INSTALL_CMOD= $(INSTALL_CMODD)/$(ABIVER)
INSTALL_MAN= $(INSTALL_SHARE)/man/man1
INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig
INSTALL_TNAME= luajit-$(VERSION)
INSTALL_TSYMNAME= luajit
INSTALL_ANAME= libluajit-$(ABIVER).a
INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER)
INSTALL_SOSHORT= libluajit-$(ABIVER).so
INSTALL_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
INSTALL_DYLIBSHORT1= libluajit-$(ABIVER).dylib
INSTALL_DYLIBSHORT2= libluajit-$(ABIVER).$(MAJVER).dylib
INSTALL_PCNAME= luajit.pc
INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME)
INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME)
INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME)
INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME)
INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
$(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
UNINSTALL_DIRS= $(INSTALL_JITLIB) $(INSTALL_LJLIBD) $(INSTALL_INC) \
$(INSTALL_LMOD) $(INSTALL_LMODD) $(INSTALL_CMOD) $(INSTALL_CMODD)
RM= rm -f
MKDIR= mkdir -p
RMDIR= rmdir 2>/dev/null
SYMLINK= ln -sf
INSTALL_X= install -m 0755
INSTALL_F= install -m 0644
UNINSTALL= $(RM)
LDCONFIG= ldconfig -n
SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|" \
-e "s|^multilib=.*|multilib=$(MULTILIB)|"
FILE_T= luajit
FILE_A= libluajit.a
FILE_SO= libluajit.so
FILE_MAN= luajit.1
FILE_PC= luajit.pc
FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
FILES_JITLIB= bc.lua bcsave.lua dump.lua p.lua v.lua zone.lua \
dis_x86.lua dis_x64.lua dis_arm.lua dis_ppc.lua \
dis_mips.lua dis_mipsel.lua vmdef.lua
ifeq (,$(findstring Windows,$(OS)))
ifeq (Darwin,$(shell uname -s))
INSTALL_SONAME= $(INSTALL_DYLIBNAME)
INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT1)
INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT2)
LDCONFIG= :
endif
endif
##############################################################################
INSTALL_DEP= src/luajit
default all $(INSTALL_DEP):
@echo "==== Building LuaJIT $(VERSION) ===="
$(MAKE) -C src
@echo "==== Successfully built LuaJIT $(VERSION) ===="
install: $(INSTALL_DEP)
@echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ===="
$(MKDIR) $(INSTALL_DIRS)
cd src && $(INSTALL_X) $(FILE_T) $(INSTALL_T)
cd src && test -f $(FILE_A) && $(INSTALL_F) $(FILE_A) $(INSTALL_STATIC) || :
$(RM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
cd src && test -f $(FILE_SO) && \
$(INSTALL_X) $(FILE_SO) $(INSTALL_DYN) && \
$(LDCONFIG) $(INSTALL_LIB) && \
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \
$(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \
$(RM) $(FILE_PC).tmp
cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC)
cd src/jit && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
@echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ===="
@echo ""
@echo "Note: the development releases deliberately do NOT install a symlink for luajit"
@echo "You can do this now by running this command (with sudo):"
@echo ""
@echo " $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)"
@echo ""
uninstall:
@echo "==== Uninstalling LuaJIT $(VERSION) from $(PREFIX) ===="
$(UNINSTALL) $(INSTALL_T) $(INSTALL_STATIC) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2) $(INSTALL_MAN)/$(FILE_MAN) $(INSTALL_PC)
for file in $(FILES_JITLIB); do \
$(UNINSTALL) $(INSTALL_JITLIB)/$$file; \
done
for file in $(FILES_INC); do \
$(UNINSTALL) $(INSTALL_INC)/$$file; \
done
$(LDCONFIG) $(INSTALL_LIB)
$(RMDIR) $(UNINSTALL_DIRS) || :
@echo "==== Successfully uninstalled LuaJIT $(VERSION) from $(PREFIX) ===="
##############################################################################
amalg:
@echo "Building LuaJIT $(VERSION)"
$(MAKE) -C src amalg
clean:
$(MAKE) -C src clean
.PHONY: all install amalg clean
##############################################################################
+16
View File
@@ -0,0 +1,16 @@
README for LuaJIT 2.1.0-beta1
-----------------------------
LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
Project Homepage: http://luajit.org/
LuaJIT is Copyright (C) 2005-2015 Mike Pall.
LuaJIT is free software, released under the MIT license.
See full Copyright Notice in the COPYRIGHT file or in luajit.h.
Documentation for LuaJIT is available in HTML format.
Please point your favorite browser to:
doc/luajit.html
Binary file not shown.
Binary file not shown.
@@ -26,8 +26,8 @@ if [[ x$NDK = "x" ]]; then
exit 1
fi
NDKABI=8
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.6
NDKABI=9
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.8
NDKP=$NDKVER/prebuilt/${host_os}-${host_arch}/bin/arm-linux-androideabi-
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
CFLAGS=""
@@ -53,6 +53,6 @@ cd src
buildLuaJIT armeabi
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)
buildLuaJIT armeabi-v7a "-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"
buildLuaJIT armeabi-v7a "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -Wl,--fix-cortex-a8"
make clean
@@ -1,4 +1,4 @@
/* Copyright (C) 2004-2013 Mike Pall.
/* Copyright (C) 2004-2015 Mike Pall.
*
* You are welcome to use the general ideas of this design for your own sites.
* But please do not steal the stylesheet, the layout or the color scheme.
@@ -1,4 +1,4 @@
/* Copyright (C) 2004-2013 Mike Pall.
/* Copyright (C) 2004-2015 Mike Pall.
*
* You are welcome to use the general ideas of this design for your own sites.
* But please do not steal the stylesheet, the layout or the color scheme.
@@ -4,7 +4,7 @@
<title>LuaJIT Change History</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -44,6 +44,8 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -63,7 +65,7 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
<div id="main">
<p>
This is a list of changes between the released versions of LuaJIT.<br>
The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;2.0.1</strong>.<br>
The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;2.0.4</strong>.<br>
</p>
<p>
Please check the
@@ -72,6 +74,178 @@ to see whether newer versions are available.
</p>
<div class="major" style="background: #d0d0ff;">
<h2 id="LuaJIT-2.1.0-beta1">LuaJIT 2.1.0-beta1 &mdash; 2015-08-25</h2>
<p>
This is a brief summary of the major changes in LuaJIT 2.1 compared to 2.0.
Please take a look at the commit history for more details.
</p>
<ul>
<li>Changes to the VM core:
<ul>
<li>Add low-overhead profiler (<tt>-jp</tt>).</li>
<li>Add <tt>LJ_GC64</tt> mode: 64 bit GC object references (really: 47 bit). Interpreter-only for now.</li>
<li>Add <tt>LJ_FR2</tt> mode: Two-slot frame info. Required by <tt>LJ_GC64</tt> mode.</li>
<li>Add <tt>table.new()</tt> and <tt>table.clear()</tt>.</li>
<li>Parse Unicode escape <tt>'\u{XX...}'</tt> in string literals.</li>
<li>Parse binary number literals (<tt>0bxxx</tt>).</li>
</ul></li>
<li>Improvements to the JIT compiler:
<ul>
<li>Add trace stitching.</li>
<li>Compile various builtins: <tt>string.char()</tt>, <tt>string.reverse()</tt>, <tt>string.lower()</tt>, <tt>string.upper()</tt>, <tt>string.rep()</tt>, <tt>string.format()</tt>, <tt>table.concat()</tt>, <tt>bit.tohex()</tt>, <tt>getfenv(0)</tt>, <tt>debug.getmetatable()</tt>.</li>
<li>Compile <tt>string.find()</tt> for fixed string searches (no patterns).</li>
<li>Compile <tt>BC_TSETM</tt>, e.g. <tt>{1,2,3,f()}</tt>.</li>
<li>Compile string concatenations (<tt>BC_CAT</tt>).</li>
<li>Compile <tt>__concat</tt> metamethod.</li>
<li>Various minor optimizations.</li>
</ul></li>
<li>Internal Changes:
<ul>
<li>Add support for embedding LuaJIT bytecode for builtins.</li>
<li>Replace various builtins with embedded bytecode.</li>
<li>Refactor string buffers and string formatting.</li>
<li>Remove obsolete non-truncating number to integer conversions.</li>
</ul></li>
<li>Ports:
<ul>
<li>Add Xbox One port (<tt>LJ_GC64</tt> mode).</li>
<li>ARM64: Add port of the interpreter (<tt>LJ_GC64</tt> mode).</li>
<li>x64: Add separate port of the interpreter to <tt>LJ_GC64</tt> mode.</li>
<li>x86/x64: Drop internal x87 math functions. Use libm functions.</li>
<li>x86: Remove x87 support from interpreter. SSE2 is mandatory now.</li>
<li>x86/x64: Add support for AES-NI, AVX and AVX2 to DynASM.</li>
<li>PPC/e500: Drop support for this architecture.</li>
</ul></li>
<li>FFI library:
<ul>
<li>FFI: Add 64 bit bitwise operations.</li>
<li>FFI: Compile VLA/VLS and large cdata allocations with default initialization.</li>
<li>FFI: Compile conversions from functions to function pointers.</li>
<li>FFI: Compile lightuserdata to <tt>void *</tt> conversion.</li>
<li>FFI: Compile <tt>ffi.gc(cdata, nil)</tt>, too.</li>
<li>FFI: Add <tt>ffi.typeinfo()</tt>.</li>
<li>FFI: Add <tt>ssize_t</tt> declaration.</li>
</ul></li>
</ul>
</div>
<div class="major" style="background: #ffffd0;">
<h2 id="LuaJIT-2.0.4">LuaJIT 2.0.4 &mdash; 2015-05-14</h2>
<ul>
<li>Fix stack check in narrowing optimization.</li>
<li>Fix Lua/C API typecheck error for special indexes.</li>
<li>Fix string to number conversion.</li>
<li>Fix lexer error for chunks without tokens.</li>
<li>Don't compile <tt>IR_RETF</tt> after <tt>CALLT</tt> to ff with-side effects.</li>
<li>Fix <tt>BC_UCLO</tt>/<tt>BC_JMP</tt> join optimization in Lua parser.</li>
<li>Fix corner case in string to number conversion.</li>
<li>Gracefully handle <tt>lua_error()</tt> for a suspended coroutine.</li>
<li>Avoid error messages when building with Clang.</li>
<li>Fix snapshot #0 handling for traces with a stack check on entry.</li>
<li>Fix fused constant loads under high register pressure.</li>
<li>Invalidate backpropagation cache after DCE.</li>
<li>Fix ABC elimination.</li>
<li>Fix debug info for main chunk of stripped bytecode.</li>
<li>Fix FOLD rule for <tt>string.sub(s, ...) == k</tt>.</li>
<li>Fix FOLD rule for <tt>STRREF</tt> of <tt>SNEW</tt>.</li>
<li>Fix frame traversal while searching for error function.</li>
<li>Prevent GC estimate miscalculation due to buffer growth.</li>
<li>Prevent adding side traces for stack checks.</li>
<li>Fix top slot calculation for snapshots with continuations.</li>
<li>Fix check for reuse of SCEV results in <tt>FORL</tt>.</li>
<li>Add PS Vita port.</li>
<li>Fix compatibility issues with Illumos.</li>
<li>Fix DragonFly build (unsupported).</li>
<li>OpenBSD/x86: Better executable memory allocation for W^X mode.</li>
<li>x86: Fix argument checks for <tt>ipairs()</tt> iterator.</li>
<li>x86: <tt>lj_math_random_step()</tt> clobbers XMM regs on OSX Clang.</li>
<li>x86: Fix code generation for unused result of <tt>math.random()</tt>.</li>
<li>x64: Allow building with <tt>LUAJIT_USE_SYSMALLOC</tt> and <tt>LUAJIT_USE_VALGRIND</tt>.</li>
<li>x86/x64: Fix argument check for bit shifts.</li>
<li>x86/x64: Fix code generation for fused test/arith ops.</li>
<li>ARM: Fix write barrier check in <tt>BC_USETS</tt>.</li>
<li>PPC: Fix red zone overflow in machine code generation.</li>
<li>PPC: Don't use <tt>mcrxr</tt> on PPE.</li>
<li>Various archs: Fix excess stack growth in interpreter.</li>
<li>FFI: Fix FOLD rule for <tt>TOBIT</tt> + <tt>CONV num.u32</tt>.</li>
<li>FFI: Prevent DSE across <tt>ffi.string()</tt>.</li>
<li>FFI: No meta fallback when indexing pointer to incomplete struct.</li>
<li>FFI: Fix initialization of unions of subtypes.</li>
<li>FFI: Fix cdata vs. non-cdata arithmetic and comparisons.</li>
<li>FFI: Fix <tt>__index</tt>/<tt>__newindex</tt> metamethod resolution for ctypes.</li>
<li>FFI: Fix compilation of reference field access.</li>
<li>FFI: Fix frame traversal for backtraces with FFI callbacks.</li>
<li>FFI: Fix recording of indexing a struct pointer ctype object itself.</li>
<li>FFI: Allow non-scalar cdata to be compared for equality by address.</li>
<li>FFI: Fix pseudo type conversions for type punning.</li>
</ul>
<h2 id="LuaJIT-2.0.3">LuaJIT 2.0.3 &mdash; 2014-03-12</h2>
<ul>
<li>Add PS4 port.</li>
<li>Add support for multilib distro builds.</li>
<li>Fix OSX build.</li>
<li>Fix MinGW build.</li>
<li>Fix Xbox 360 build.</li>
<li>Improve ULOAD forwarding for open upvalues.</li>
<li>Fix GC steps threshold handling when called by JIT-compiled code.</li>
<li>Fix argument checks for <tt>math.deg()</tt> and <tt>math.rad()</tt>.</li>
<li>Fix <tt>jit.flush(func|true)</tt>.</li>
<li>Respect <tt>jit.off(func)</tt> when returning to a function, too.</li>
<li>Fix compilation of <tt>string.byte(s, nil, n)</tt>.</li>
<li>Fix line number for relocated bytecode after closure fixup</li>
<li>Fix frame traversal for backtraces.</li>
<li>Fix ABC elimination.</li>
<li>Fix handling of redundant PHIs.</li>
<li>Fix snapshot restore for exit to function header.</li>
<li>Fix type punning alias analysis for constified pointers</li>
<li>Fix call unroll checks in the presence of metamethod frames.</li>
<li>Fix initial maxslot for down-recursive traces.</li>
<li>Prevent BASE register coalescing if parent uses <tt>IR_RETF</tt>.</li>
<li>Don't purge modified function from stack slots in <tt>BC_RET</tt>.</li>
<li>Fix recording of <tt>BC_VARG</tt>.</li>
<li>Don't access dangling reference to reallocated IR.</li>
<li>Fix frame depth display for bytecode dump in <tt>-jdump</tt>.</li>
<li>ARM: Fix register allocation when rematerializing FPRs.</li>
<li>x64: Fix store to upvalue for lightuserdata values.</li>
<li>FFI: Add missing GC steps for callback argument conversions.</li>
<li>FFI: Properly unload loaded DLLs.</li>
<li>FFI: Fix argument checks for <tt>ffi.string()</tt>.</li>
<li>FFI/x64: Fix passing of vector arguments to calls.</li>
<li>FFI: Rehash finalizer table after GC cycle, if needed.</li>
<li>FFI: Fix <tt>cts-&gt;L</tt> for cdata unsinking in snapshot restore.</li>
</ul>
<h2 id="LuaJIT-2.0.2">LuaJIT 2.0.2 &mdash; 2013-06-03</h2>
<ul>
<li>Fix memory access check for fast string interning.</li>
<li>Fix MSVC intrinsics for older versions.</li>
<li>Add missing GC steps for <tt>io.*</tt> functions.</li>
<li>Fix spurious red zone overflows in machine code generation.</li>
<li>Fix jump-range constrained mcode allocation.</li>
<li>Inhibit DSE for implicit loads via calls.</li>
<li>Fix builtin string to number conversion for overflow digits.</li>
<li>Fix optional argument handling while recording builtins.</li>
<li>Fix optional argument handling in <tt>table.concat()</tt>.</li>
<li>Add partial support for building with MingW64 GCC 4.8-SEH.</li>
<li>Add missing PHI barrier to <tt>string.sub(str, a, b) == kstr</tt> FOLD rule.</li>
<li>Fix compatibility issues with Illumos.</li>
<li>ARM: Fix cache flush/sync for exit stubs of JIT-compiled code.</li>
<li>MIPS: Fix cache flush/sync for JIT-compiled code jump area.</li>
<li>PPC: Add <tt>plt</tt> suffix for external calls from assembler code.</li>
<li>FFI: Fix snapshot substitution in SPLIT pass.</li>
<li>FFI/x86: Fix register allocation for 64 bit comparisons.</li>
<li>FFI: Fix tailcall in lowest frame to C&nbsp;function with bool result.</li>
<li>FFI: Ignore <tt>long</tt> type specifier in <tt>ffi.istype()</tt>.</li>
<li>FFI: Fix calling conventions for 32 bit OSX and iOS simulator (struct returns).</li>
<li>FFI: Fix calling conventions for ARM hard-float EABI (nested structs).</li>
<li>FFI: Improve error messages for arithmetic and comparison operators.</li>
<li>FFI: Insert no-op type conversion for pointer to integer cast.</li>
<li>FFI: Fix unroll limit for <tt>ffi.fill()</tt>.</li>
<li>FFI: Must sink <tt>XBAR</tt> together with <tt>XSTORE</tt>s.</li>
<li>FFI: Preserve intermediate string for <tt>const&nbsp;char&nbsp;*</tt> conversion.</li>
</ul>
<h2 id="LuaJIT-2.0.1">LuaJIT 2.0.1 &mdash; 2013-02-19</h2>
<ul>
<li>Don't clear frame for out-of-memory error.</li>
@@ -619,240 +793,11 @@ This matches the behavior of Lua 5.1, but not the specification.</li>
no point in listing differences over earlier versions.</li>
</ul>
</div>
<div class="major" style="background: #ffff80;">
<h2 id="LuaJIT-1.1.8">LuaJIT 1.1.8 &mdash; 2012-04-16</h2>
<ul>
<li>Merged with Lua 5.1.5. Also integrated fixes for all
<a href="http://www.lua.org/bugs.html#5.1.5"><span class="ext">&raquo;</span>&nbsp;<span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.5</a>.</li>
</ul>
<h2 id="LuaJIT-1.1.7">LuaJIT 1.1.7 &mdash; 2011-05-05</h2>
<ul>
<li>Added fixes for the
<a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.4</a>.</li>
</ul>
<h2 id="LuaJIT-1.1.6">LuaJIT 1.1.6 &mdash; 2010-03-28</h2>
<ul>
<li>Added fixes for the
<a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.4</a>.</li>
<li>Removed wrong GC check in <tt>jit_createstate()</tt>.
Thanks to Tim Mensch.</li>
<li>Fixed bad assertions while compiling <tt>table.insert()</tt> and
<tt>table.remove()</tt>.</li>
</ul>
<h2 id="LuaJIT-1.1.5">LuaJIT 1.1.5 &mdash; 2008-10-25</h2>
<ul>
<li>Merged with Lua 5.1.4. Fixes all
<a href="http://www.lua.org/bugs.html#5.1.3"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.3</a>.</li>
</ul>
<h2 id="LuaJIT-1.1.4">LuaJIT 1.1.4 &mdash; 2008-02-05</h2>
<ul>
<li>Merged with Lua 5.1.3. Fixes all
<a href="http://www.lua.org/bugs.html#5.1.2"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.2</a>.</li>
<li>Fixed possible (but unlikely) stack corruption while compiling
<tt>k^x</tt> expressions.</li>
<li>Fixed DynASM template for cmpss instruction.</li>
</ul>
<h2 id="LuaJIT-1.1.3">LuaJIT 1.1.3 &mdash; 2007-05-24</h2>
<ul>
<li>Merged with Lua 5.1.2. Fixes all
<a href="http://www.lua.org/bugs.html#5.1.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.1</a>.</li>
<li>Merged pending Lua 5.1.x fixes: "return -nil" bug, spurious count hook call.</li>
<li>Remove a (sometimes) wrong assertion in <tt>luaJIT_findpc()</tt>.</li>
<li>DynASM now allows labels for displacements and <tt>.aword</tt>.</li>
<li>Fix some compiler warnings for DynASM glue (internal API change).</li>
<li>Correct naming for SSSE3 (temporarily known as SSE4) in DynASM and x86 disassembler.</li>
<li>The loadable debug modules now handle redirection to stdout
(e.g. <tt>-j&nbsp;trace=-</tt>).</li>
</ul>
<h2 id="LuaJIT-1.1.2">LuaJIT 1.1.2 &mdash; 2006-06-24</h2>
<ul>
<li>Fix MSVC inline assembly: use only local variables with
<tt>lua_number2int()</tt>.</li>
<li>Fix "attempt to call a thread value" bug on Mac OS X:
make values of consts used as lightuserdata keys unique
to avoid joining by the compiler/linker.</li>
</ul>
<h2 id="LuaJIT-1.1.1">LuaJIT 1.1.1 &mdash; 2006-06-20</h2>
<ul>
<li>Merged with Lua 5.1.1. Fixes all
<a href="http://www.lua.org/bugs.html#5.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1</a>.</li>
<li>Enforce (dynamic) linker error for EXE/DLL version mismatches.</li>
<li>Minor changes to DynASM: faster pre-processing, smaller encoding
for some immediates.</li>
</ul>
<p>
This release is in sync with Coco 1.1.1 (see the
<a href="http://coco.luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Coco Change History</a>).
</p>
<h2 id="LuaJIT-1.1.0">LuaJIT 1.1.0 &mdash; 2006-03-13</h2>
<ul>
<li>Merged with Lua 5.1 (final).</li>
<li>New JIT call frame setup:
<ul>
<li>The C stack is kept 16 byte aligned (faster).
Mandatory for Mac OS X on Intel, too.</li>
<li>Faster calling conventions for internal C helper functions.</li>
<li>Better instruction scheduling for function prologue, OP_CALL and
OP_RETURN.</li>
</ul></li>
<li>Miscellaneous optimizations:
<ul>
<li>Faster loads of FP constants. Remove narrow-to-wide store-to-load
forwarding stalls.</li>
<li>Use (scalar) SSE2 ops (if the CPU supports it) to speed up slot moves
and FP to integer conversions.</li>
<li>Optimized the two-argument form of <tt>OP_CONCAT</tt> (<tt>a..b</tt>).</li>
<li>Inlined <tt>OP_MOD</tt> (<tt>a%b</tt>).
With better accuracy than the C variant, too.</li>
<li>Inlined <tt>OP_POW</tt> (<tt>a^b</tt>). Unroll <tt>x^k</tt> or
use <tt>k^x = 2^(log2(k)*x)</tt> or call <tt>pow()</tt>.</li>
</ul></li>
<li>Changes in the optimizer:
<ul>
<li>Improved hinting for table keys derived from table values
(<tt>t1[t2[x]]</tt>).</li>
<li>Lookup hinting now works with arbitrary object types and
supports index chains, too.</li>
<li>Generate type hints for arithmetic and comparison operators,
OP_LEN, OP_CONCAT and OP_FORPREP.</li>
<li>Remove several hint definitions in favour of a generic COMBINE hint.</li>
<li>Complete rewrite of <tt>jit.opt_inline</tt> module
(ex <tt>jit.opt_lib</tt>).</li>
</ul></li>
<li>Use adaptive deoptimization:
<ul>
<li>If runtime verification of a contract fails, the affected
instruction is recompiled and patched on-the-fly.
Regular programs will trigger deoptimization only occasionally.</li>
<li>This avoids generating code for uncommon fallback cases
most of the time. Generated code is up to 30% smaller compared to
LuaJIT&nbsp;1.0.3.</li>
<li>Deoptimization is used for many opcodes and contracts:
<ul>
<li>OP_CALL, OP_TAILCALL: type mismatch for callable.</li>
<li>Inlined calls: closure mismatch, parameter number and type mismatches.</li>
<li>OP_GETTABLE, OP_SETTABLE: table or key type and range mismatches.</li>
<li>All arithmetic and comparison operators, OP_LEN, OP_CONCAT,
OP_FORPREP: operand type and range mismatches.</li>
</ul></li>
<li>Complete redesign of the debug and traceback info
(bytecode &harr; mcode) to support deoptimization.
Much more flexible and needs only 50% of the space.</li>
<li>The modules <tt>jit.trace</tt>, <tt>jit.dumphints</tt> and
<tt>jit.dump</tt> handle deoptimization.</li>
</ul></li>
<li>Inlined many popular library functions
(for commonly used arguments only):
<ul>
<li>Most <tt>math.*</tt> functions (the 18 most used ones)
[2x-10x faster].</li>
<li><tt>string.len</tt>, <tt>string.sub</tt> and <tt>string.char</tt>
[2x-10x faster].</li>
<li><tt>table.insert</tt>, <tt>table.remove</tt> and <tt>table.getn</tt>
[3x-5x faster].</li>
<li><tt>coroutine.yield</tt> and <tt>coroutine.resume</tt>
[3x-5x faster].</li>
<li><tt>pairs</tt>, <tt>ipairs</tt> and the corresponding iterators
[8x-15x faster].</li>
</ul></li>
<li>Changes in the core and loadable modules and the stand-alone executable:
<ul>
<li>Added <tt>jit.version</tt>, <tt>jit.version_num</tt>
and <tt>jit.arch</tt>.</li>
<li>Reorganized some internal API functions (<tt>jit.util.*mcode*</tt>).</li>
<li>The <tt>-j dump</tt> output now shows JSUB names, too.</li>
<li>New x86 disassembler module written in pure Lua. No dependency
on ndisasm anymore. Flexible API, very compact (500 lines)
and complete (x87, MMX, SSE, SSE2, SSE3, SSSE3, privileged instructions).</li>
<li><tt>luajit -v</tt> prints the LuaJIT version and copyright
on a separate line.</li>
</ul></li>
<li>Added SSE, SSE2, SSE3 and SSSE3 support to DynASM.</li>
<li>Miscellaneous doc changes. Added a section about
<a href="install.html#embedding">embedding LuaJIT</a>.</li>
</ul>
<p>
This release is in sync with Coco 1.1.0 (see the
<a href="http://coco.luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Coco Change History</a>).
</p>
</div>
<div class="major" style="background: #ffffd0;">
<h2 id="LuaJIT-1.0.3">LuaJIT 1.0.3 &mdash; 2005-09-08</h2>
<ul>
<li>Even more docs.</li>
<li>Unified closure checks in <tt>jit.*</tt>.</li>
<li>Fixed some range checks in <tt>jit.util.*</tt>.</li>
<li>Fixed __newindex call originating from <tt>jit_settable_str()</tt>.</li>
<li>Merged with Lua 5.1 alpha (including early bug fixes).</li>
</ul>
<p>
This is the first public release of LuaJIT.
</p>
<h2 id="LuaJIT-1.0.2">LuaJIT 1.0.2 &mdash; 2005-09-02</h2>
<ul>
<li>Add support for flushing the Valgrind translation cache <br>
(<tt>MYCFLAGS= -DUSE_VALGRIND</tt>).</li>
<li>Add support for freeing executable mcode memory to the <tt>mmap()</tt>-based
variant for POSIX systems.</li>
<li>Reorganized the C&nbsp;function signature handling in
<tt>jit.opt_lib</tt>.</li>
<li>Changed to index-based hints for inlining C&nbsp;functions.
Still no support in the backend for inlining.</li>
<li>Hardcode <tt>HEAP_CREATE_ENABLE_EXECUTE</tt> value if undefined.</li>
<li>Misc. changes to the <tt>jit.*</tt> modules.</li>
<li>Misc. changes to the Makefiles.</li>
<li>Lots of new docs.</li>
<li>Complete doc reorg.</li>
</ul>
<p>
Not released because Lua 5.1 alpha came out today.
</p>
<h2 id="LuaJIT-1.0.1">LuaJIT 1.0.1 &mdash; 2005-08-31</h2>
<ul>
<li>Missing GC step in <tt>OP_CONCAT</tt>.</li>
<li>Fix result handling for C &ndash;> JIT calls.</li>
<li>Detect CPU feature bits.</li>
<li>Encode conditional moves (<tt>fucomip</tt>) only when supported.</li>
<li>Add fallback instructions for FP compares.</li>
<li>Add support for <tt>LUA_COMPAT_VARARG</tt>. Still disabled by default.</li>
<li>MSVC needs a specific place for the <tt>CALLBACK</tt> attribute
(David Burgess).</li>
<li>Misc. doc updates.</li>
</ul>
<p>
Interim non-public release.
Special thanks to Adam D. Moss for reporting most of the bugs.
</p>
<h2 id="LuaJIT-1.0.0">LuaJIT 1.0.0 &mdash; 2005-08-29</h2>
<p>
This is the initial non-public release of LuaJIT.
</p>
</div>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>Contact</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -41,6 +41,8 @@
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -84,7 +86,7 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D")
<h2>Copyright</h2>
<p>
All documentation is
Copyright &copy; 2005-2013 Mike Pall.
Copyright &copy; 2005-2015 Mike Pall.
</p>
@@ -92,7 +94,7 @@ Copyright &copy; 2005-2013 Mike Pall.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>Lua/C API Extensions</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -41,6 +41,8 @@
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a class="current" href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -177,7 +179,7 @@ Also note that this mechanism is not without overhead.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>FFI Library</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -41,6 +41,8 @@
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -320,7 +322,7 @@ without undue conversion penalties.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>ffi.* API Functions</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -46,6 +46,8 @@ td.abiparam { font-weight: bold; width: 6em; }
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -466,6 +468,8 @@ otherwise. The following parameters are currently defined:
<td class="abiparam">eabi</td><td class="abidesc">EABI variant of the standard ABI</td></tr>
<tr class="odd">
<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
<tr class="even">
<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
</table>
<h3 id="ffi_os"><tt>ffi.os</tt></h3>
@@ -542,8 +546,8 @@ corresponding ctype.
The parser for Lua source code treats numeric literals with the
suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64&nbsp;bit
integers. Case doesn't matter, but uppercase is recommended for
readability. It handles both decimal (<tt>42LL</tt>) and hexadecimal
(<tt>0x2aLL</tt>) literals.
readability. It handles decimal (<tt>42LL</tt>), hexadecimal
(<tt>0x2aLL</tt>) and binary (<tt>0b101010LL</tt>) literals.
</p>
<p>
The imaginary part of complex numbers can be specified by suffixing
@@ -556,7 +560,7 @@ named <tt>i</tt>.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>FFI Semantics</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -46,6 +46,8 @@ td.convop { font-style: italic; width: 40%; }
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -183,6 +185,8 @@ a <tt>typedef</tt>, except re-declarations will be ignored):
<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>,
<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li>
<li>From <tt>&lt;unistd.h&gt;</tt> (POSIX): <tt>ssize_t</tt>.</li>
</ul>
<p>
You're encouraged to use these types in preference to
@@ -730,6 +734,22 @@ You'll have to explicitly convert a 64&nbsp;bit integer to a Lua
number (e.g. for regular floating-point calculations) with
<tt>tonumber()</tt>. But note this may incur a precision loss.</li>
<li><b>64&nbsp;bit bitwise operations</b>: the rules for 64&nbsp;bit
arithmetic operators apply analogously.<br>
Unlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt>
converts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and
returns a Lua number.<br>
For <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the
conversion to <tt>int64_t</tt> or <tt>uint64_t</tt> applies to
<em>all</em> arguments, if <em>any</em> argument is a cdata number.<br>
For all other operations, only the first argument is used to determine
the output type. This implies that a cdata number as a shift count for
shifts and rotates is accepted, but that alone does <em>not</em> cause
a cdata number output.
</ul>
<h3 id="cdata_comp">Comparisons of cdata objects</h3>
@@ -1188,7 +1208,9 @@ storing and initializing them are supported, yet.</li>
<li>The <tt>volatile</tt> type qualifier is currently ignored by
compiled code.</li>
<li><a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a> silently
ignores all re-declarations.</li>
ignores most re-declarations. Note: avoid re-declarations which do not
conform to C99. The implementation will eventually be changed to
perform strict checks.</li>
</ul>
<p>
The JIT compiler already handles a large subset of all FFI operations.
@@ -1203,9 +1225,8 @@ suboptimal performance, especially when used in inner loops:
<li>Vector operations.</li>
<li>Table initializers.</li>
<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
<li>Allocations of variable-length arrays or structs.</li>
<li>Allocations of C&nbsp;types with a size &gt; 128&nbsp;bytes or an
alignment &gt; 8&nbsp;bytes.</li>
<li>Non-default initialization of VLA/VLS or large C&nbsp;types
(&gt; 128&nbsp;bytes or &gt; 16 array elements.</li>
<li>Conversions from lightuserdata to <tt>void&nbsp;*</tt>.</li>
<li>Pointer differences for element sizes that are not a power of
two.</li>
@@ -1222,7 +1243,6 @@ value.</li>
Other missing features:
</p>
<ul>
<li>Bit operations for 64&nbsp;bit types.</li>
<li>Arithmetic for <tt>complex</tt> numbers.</li>
<li>Passing structs by value to vararg C&nbsp;functions.</li>
<li><a href="extensions.html#exceptions">C++ exception interoperability</a>
@@ -1233,7 +1253,7 @@ compiled.</li>
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>FFI Tutorial</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -48,6 +48,8 @@ td.idiomlua b { font-weight: normal; color: #2142bf; }
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -564,7 +566,7 @@ Thus it's not helpful and actually counter-productive to cache
individual C&nbsp;functions like this:
</p>
<pre class="code">
local <b>funca</b>, <b>funcb</b> = ffi.C.funcb, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span>
local <b>funca</b>, <b>funcb</b> = ffi.C.funca, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span>
local function foo(x, n)
for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end
end
@@ -591,7 +593,7 @@ it to a local variable in the function scope is unnecessary.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>jit.* Library</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -41,6 +41,8 @@
<a class="current" href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -151,7 +153,7 @@ Contains the target OS name:
<h3 id="jit_arch"><tt>jit.arch</tt></h3>
<p>
Contains the target architecture name:
"x86", "x64" or "ppcspe".
"x86", "x64", "arm", "ppc", or "mips".
</p>
<h2 id="jit_opt"><tt>jit.opt.*</tt> &mdash; JIT compiler optimization control</h2>
@@ -189,7 +191,7 @@ if you want to know more.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
+365
View File
@@ -0,0 +1,365 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Profiler</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
</head>
<body>
<div id="site">
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>Profiler</h1>
</div>
<div id="nav">
<ul><li>
<a href="luajit.html">LuaJIT</a>
<ul><li>
<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
</li><li>
<a href="install.html">Installation</a>
</li><li>
<a href="running.html">Running</a>
</li></ul>
</li><li>
<a href="extensions.html">Extensions</a>
<ul><li>
<a href="ext_ffi.html">FFI Library</a>
<ul><li>
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
</li><li>
<a href="ext_ffi_api.html">ffi.* API</a>
</li><li>
<a href="ext_ffi_semantics.html">FFI Semantics</a>
</li></ul>
</li><li>
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a class="current" href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
<ul><li>
<a href="changes.html">Changes</a>
</li></ul>
</li><li>
<a href="faq.html">FAQ</a>
</li><li>
<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
</li><li>
<a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
</li><li>
<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
</li></ul>
</div>
<div id="main">
<p>
LuaJIT has an integrated statistical profiler with very low overhead. It
allows sampling the currently executing stack and other parameters in
regular intervals.
</p>
<p>
The integrated profiler can be accessed from three levels:
</p>
<ul>
<li>The <a href="#hl_profiler">bundled high-level profiler</a>, invoked by the
<a href="#j_p"><tt>-jp</tt></a> command line option.</li>
<li>A <a href="#ll_lua_api">low-level Lua API</a> to control the profiler.</li>
<li>A <a href="#ll_c_api">low-level C API</a> to control the profiler.</li>
</ul>
<h2 id="hl_profiler">High-Level Profiler</h2>
<p>
The bundled high-level profiler offers basic profiling functionality. It
generates simple textual summaries or source code annotations. It can be
accessed with the <a href="#j_p"><tt>-jp</tt></a> command line option
or from Lua code by loading the underlying <tt>jit.p</tt> module.
</p>
<p>
To cut to the chase &mdash; run this to get a CPU usage profile by
function name:
</p>
<pre class="code">
luajit -jp myapp.lua
</pre>
<p>
It's <em>not</em> a stated goal of the bundled profiler to add every
possible option or to cater for special profiling needs. The low-level
profiler APIs are documented below. They may be used by third-party
authors to implement advanced functionality, e.g. IDE integration or
graphical profilers.
</p>
<p>
Note: Sampling works for both interpreted and JIT-compiled code. The
results for JIT-compiled code may sometimes be surprising. LuaJIT
heavily optimizes and inlines Lua code &mdash; there's no simple
one-to-one correspondence between source code lines and the sampled
machine code.
</p>
<h3 id="j_p"><tt>-jp=[options[,output]]</tt></h3>
<p>
The <tt>-jp</tt> command line option starts the high-level profiler.
When the application run by the command line terminates, the profiler
stops and writes the results to <tt>stdout</tt> or to the specified
<tt>output</tt> file.
</p>
<p>
The <tt>options</tt> argument specifies how the profiling is to be
performed:
</p>
<ul>
<li><tt>f</tt> &mdash; Stack dump: function name, otherwise module:line.
This is the default mode.</li>
<li><tt>F</tt> &mdash; Stack dump: ditto, but dump module:name.</li>
<li><tt>l</tt> &mdash; Stack dump: module:line.</li>
<li><tt>&lt;number&gt;</tt> &mdash; stack dump depth (callee &larr;
caller). Default: 1.</li>
<li><tt>-&lt;number&gt;</tt> &mdash; Inverse stack dump depth (caller
&rarr; callee).</li>
<li><tt>s</tt> &mdash; Split stack dump after first stack level. Implies
depth&nbsp;&ge;&nbsp;2 or depth&nbsp;&le;&nbsp;-2.</li>
<li><tt>p</tt> &mdash; Show full path for module names.</li>
<li><tt>v</tt> &mdash; Show VM states.</li>
<li><tt>z</tt> &mdash; Show <a href="#jit_zone">zones</a>.</li>
<li><tt>r</tt> &mdash; Show raw sample counts. Default: show percentages.</li>
<li><tt>a</tt> &mdash; Annotate excerpts from source code files.</li>
<li><tt>A</tt> &mdash; Annotate complete source code files.</li>
<li><tt>G</tt> &mdash; Produce raw output suitable for graphical tools.</li>
<li><tt>m&lt;number&gt;</tt> &mdash; Minimum sample percentage to be shown.
Default: 3%.</li>
<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds.
Default: 10ms.<br>
Note: The actual sampling precision is OS-dependent.</li>
</ul>
<p>
The default output for <tt>-jp</tt> is a list of the most CPU consuming
spots in the application. Increasing the stack dump depth with (say)
<tt>-jp=2</tt> may help to point out the main callers or callees of
hotspots. But sample aggregation is still flat per unique stack dump.
</p>
<p>
To get a two-level view (split view) of callers/callees, use
<tt>-jp=s</tt> or <tt>-jp=-s</tt>. The percentages shown for the second
level are relative to the first level.
</p>
<p>
To see how much time is spent in each line relative to a function, use
<tt>-jp=fl</tt>.
</p>
<p>
To see how much time is spent in different VM states or
<a href="#jit_zone">zones</a>, use <tt>-jp=v</tt> or <tt>-jp=z</tt>.
</p>
<p>
Combinations of <tt>v/z</tt> with <tt>f/F/l</tt> produce two-level
views, e.g. <tt>-jp=vf</tt> or <tt>-jp=fv</tt>. This shows the time
spent in a VM state or zone vs. hotspots. This can be used to answer
questions like "Which time consuming functions are only interpreted?" or
"What's the garbage collector overhead for a specific function?".
</p>
<p>
Multiple options can be combined &mdash; but not all combinations make
sense, see above. E.g. <tt>-jp=3si4m1</tt> samples three stack levels
deep in 4ms intervals and shows a split view of the CPU consuming
functions and their callers with a 1% threshold.
</p>
<p>
Source code annotations produced by <tt>-jp=a</tt> or <tt>-jp=A</tt> are
always flat and at the line level. Obviously, the source code files need
to be readable by the profiler script.
</p>
<p>
The high-level profiler can also be started and stopped from Lua code with:
</p>
<pre class="code">
require("jit.p").start(options, output)
...
require("jit.p").stop()
</pre>
<h3 id="jit_zone"><tt>jit.zone</tt> &mdash; Zones</h3>
<p>
Zones can be used to provide information about different parts of an
application to the high-level profiler. E.g. a game could make use of an
<tt>"AI"</tt> zone, a <tt>"PHYS"</tt> zone, etc. Zones are hierarchical,
organized as a stack.
</p>
<p>
The <tt>jit.zone</tt> module needs to be loaded explicitly:
</p>
<pre class="code">
local zone = require("jit.zone")
</pre>
<ul>
<li><tt>zone("name")</tt> pushes a named zone to the zone stack.</li>
<li><tt>zone()</tt> pops the current zone from the zone stack and
returns its name.</li>
<li><tt>zone:get()</tt> returns the current zone name or <tt>nil</tt>.</li>
<li><tt>zone:flush()</tt> flushes the zone stack.</li>
</ul>
<p>
To show the time spent in each zone use <tt>-jp=z</tt>. To show the time
spent relative to hotspots use e.g. <tt>-jp=zf</tt> or <tt>-jp=fz</tt>.
</p>
<h2 id="ll_lua_api">Low-level Lua API</h2>
<p>
The <tt>jit.profile</tt> module gives access to the low-level API of the
profiler from Lua code. This module needs to be loaded explicitly:
<pre class="code">
local profile = require("jit.profile")
</pre>
<p>
This module can be used to implement your own higher-level profiler.
A typical profiling run starts the profiler, captures stack dumps in
the profiler callback, adds them to a hash table to aggregate the number
of samples, stops the profiler and then analyzes all of the captured
stack dumps. Other parameters can be sampled in the profiler callback,
too. But it's important not to spend too much time in the callback,
since this may skew the statistics.
</p>
<h3 id="profile_start"><tt>profile.start(mode, cb)</tt>
&mdash; Start profiler</h3>
<p>
This function starts the profiler. The <tt>mode</tt> argument is a
string holding options:
</p>
<ul>
<li><tt>f</tt> &mdash; Profile with precision down to the function level.</li>
<li><tt>l</tt> &mdash; Profile with precision down to the line level.</li>
<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds (default
10ms).</br>
Note: The actual sampling precision is OS-dependent.
</li>
</ul>
<p>
The <tt>cb</tt> argument is a callback function which is called with
three arguments: <tt>(thread, samples, vmstate)</tt>. The callback is
called on a separate coroutine, the <tt>thread</tt> argument is the
state that holds the stack to sample for profiling. Note: do
<em>not</em> modify the stack of that state or call functions on it.
</p>
<p>
<tt>samples</tt> gives the number of accumulated samples since the last
callback (usually 1).
</p>
<p>
<tt>vmstate</tt> holds the VM state at the time the profiling timer
triggered. This may or may not correspond to the state of the VM when
the profiling callback is called. The state is either <tt>'N'</tt>
native (compiled) code, <tt>'I'</tt> interpreted code, <tt>'C'</tt>
C&nbsp;code, <tt>'G'</tt> the garbage collector, or <tt>'J'</tt> the JIT
compiler.
</p>
<h3 id="profile_stop"><tt>profile.stop()</tt>
&mdash; Stop profiler</h3>
<p>
This function stops the profiler.
</p>
<h3 id="profile_dump"><tt>dump = profile.dumpstack([thread,] fmt, depth)</tt>
&mdash; Dump stack </h3>
<p>
This function allows taking stack dumps in an efficient manner. It
returns a string with a stack dump for the <tt>thread</tt> (coroutine),
formatted according to the <tt>fmt</tt> argument:
</p>
<ul>
<li><tt>p</tt> &mdash; Preserve the full path for module names. Otherwise
only the file name is used.</li>
<li><tt>f</tt> &mdash; Dump the function name if it can be derived. Otherwise
use module:line.</li>
<li><tt>F</tt> &mdash; Ditto, but dump module:name.</li>
<li><tt>l</tt> &mdash; Dump module:line.</li>
<li><tt>Z</tt> &mdash; Zap the following characters for the last dumped
frame.</li>
<li>All other characters are added verbatim to the output string.</li>
</ul>
<p>
The <tt>depth</tt> argument gives the number of frames to dump, starting
at the topmost frame of the thread. A negative number dumps the frames in
inverse order.
</p>
<p>
The first example prints a list of the current module names and line
numbers of up to 10 frames in separate lines. The second example prints
semicolon-separated function names for all frames (up to 100) in inverse
order:
</p>
<pre class="code">
print(profile.dumpstack(thread, "l\n", 10))
print(profile.dumpstack(thread, "lZ;", -100))
</pre>
<h2 id="ll_c_api">Low-level C API</h2>
<p>
The profiler can be controlled directly from C&nbsp;code, e.g. for
use by IDEs. The declarations are in <tt>"luajit.h"</tt> (see
<a href="ext_c_api.html">Lua/C API</a> extensions).
</p>
<h3 id="luaJIT_profile_start"><tt>luaJIT_profile_start(L, mode, cb, data)</tt>
&mdash; Start profiler</h3>
<p>
This function starts the profiler. <a href="#profile_start">See
above</a> for a description of the <tt>mode</tt> argument.
</p>
<p>
The <tt>cb</tt> argument is a callback function with the following
declaration:
</p>
<pre class="code">
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
int samples, int vmstate);
</pre>
<p>
<tt>data</tt> is available for use by the callback. <tt>L</tt> is the
state that holds the stack to sample for profiling. Note: do
<em>not</em> modify this stack or call functions on this stack &mdash;
use a separate coroutine for this purpose. <a href="#profile_start">See
above</a> for a description of <tt>samples</tt> and <tt>vmstate</tt>.
</p>
<h3 id="luaJIT_profile_stop"><tt>luaJIT_profile_stop(L)</tt>
&mdash; Stop profiler</h3>
<p>
This function stops the profiler.
</p>
<h3 id="luaJIT_profile_dumpstack"><tt>p = luaJIT_profile_dumpstack(L, fmt, depth, len)</tt>
&mdash; Dump stack </h3>
<p>
This function allows taking stack dumps in an efficient manner.
<a href="#profile_dump">See above</a> for a description of <tt>fmt</tt>
and <tt>depth</tt>.
</p>
<p>
This function returns a <tt>const&nbsp;char&nbsp;*</tt> pointing to a
private string buffer of the profiler. The <tt>int&nbsp;*len</tt>
argument returns the length of the output string. The buffer is
overwritten on the next call and deallocated when the profiler stops.
You either need to consume the content immediately or copy it for later
use.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>
@@ -4,7 +4,7 @@
<title>Extensions</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -58,6 +58,8 @@ td.excinterop {
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -113,6 +115,9 @@ bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
This module is a LuaJIT built-in &mdash; you don't need to download or
install Lua BitOp. The Lua BitOp site has full documentation for all
<a href="http://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>.
The FFI adds support for
<a href="ext_ffi_semantics.html#cdata_arith">64&nbsp;bit bitwise operations</a>,
using the same API functions.
</p>
<p>
Please make sure to <tt>require</tt> the module before using any of
@@ -146,6 +151,11 @@ LuaJIT adds some
<a href="ext_c_api.html">extra functions to the Lua/C API</a>.
</p>
<h3 id="profiler">Profiler</h3>
<p>
LuaJIT has an <a href="ext_profiler.html">integrated profiler</a>.
</p>
<h2 id="library">Enhanced Standard Library Functions</h2>
<h3 id="xpcall"><tt>xpcall(f, err [,args...])</tt> passes arguments</h3>
@@ -173,7 +183,7 @@ in <tt>"-inf"</tt>.
<h3 id="tonumber"><tt>tonumber()</tt> etc. use builtin string to number conversion</h3>
<p>
All string-to-number conversions consistently convert integer and
floating-point inputs in decimal and hexadecimal on all platforms.
floating-point inputs in decimal, hexadecimal and binary on all platforms.
<tt>strtod()</tt> is <em>not</em> used anymore, which avoids numerous
problems with poor C library implementations. The builtin conversion
function provides full precision according to the IEEE-754 standard, it
@@ -197,6 +207,36 @@ for dot releases (x.y.0 &rarr; x.y.1), but may change with major or
minor releases (2.0 &rarr; 2.1) or between any beta release. Foreign
bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
</p>
<p>
Note: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies
a different, incompatible bytecode format for ports that use this mode (e.g.
ARM64). This may be rectified in the future.
</p>
<h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>
<p>
An extra library function <tt>table.new()</tt> can be made available via
<tt>require("table.new")</tt>. This creates a pre-sized table, just like
the C API equivalent <tt>lua_createtable()</tt>. This is useful for big
tables if the final table size is known and automatic table resizing is
too expensive.
</p>
<h3 id="table_clear"><tt>table.clear(tab)</tt> clears a table</h3>
<p>
An extra library function <tt>table.clear()</tt> can be made available
via <tt>require("table.clear")</tt>. This clears all keys and values
from a table, but preserves the allocated array/hash sizes. This is
useful when a table, which is linked from multiple places, needs to be
cleared and/or when recycling a table for use by the same context. This
avoids managing backlinks, saves an allocation and the overhead of
incremental array/hash part growth.
</p>
<p>
Please note this function is meant for very specific situations. In most
cases it's better to replace the (usually single) link with a new table
and let the GC do its work.
</p>
<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
<p>
@@ -248,8 +288,9 @@ enabled:
<ul>
<li><tt>goto</tt> and <tt>::labels::</tt>.</li>
<li>Hex escapes <tt>'\x3F'</tt> and <tt>'\*'</tt> escape in strings.</li>
<li><tt>load(string|reader, chunkname [,mode [,env]])</tt>.
<tt>loadstring()</tt> is an alias.</li>
<li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li>
<li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li>
<li><tt>loadfile(filename [,mode [,env]])</tt>.</li>
<li><tt>math.log(x [,base])</tt>.
<li><tt>string.rep(s, n [,sep])</tt>.
<li><tt>string.format()</tt>: <tt>%q</tt> reversible.
@@ -303,6 +344,13 @@ Lua&nbsp;5.1, which prevents implementing features that would otherwise
break the Lua/C API and ABI (e.g. <tt>_ENV</tt>).
</p>
<h2 id="lua53">Extensions from Lua 5.3</h2>
<p>
LuaJIT supports some extensions from Lua&nbsp;5.3:
<ul>
<li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>
</ul>
<h2 id="exceptions">C++ Exception Interoperability</h2>
<p>
LuaJIT has built-in support for interoperating with C++&nbsp;exceptions.
@@ -397,7 +445,7 @@ lead to the termination of the process.</li>
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>Frequently Asked Questions (FAQ)</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -44,6 +44,8 @@ dd { margin-left: 1.5em; }
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -174,7 +176,7 @@ the development of certain features, if they are important to you.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -4,7 +4,7 @@
<title>Installation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -69,6 +69,8 @@ td.compatno {
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -112,39 +114,39 @@ operating systems, CPUs and compilers:
</tr>
<tr class="odd separate">
<td class="compatcpu">x86 (32 bit)</td>
<td class="compatos">GCC 4.x<br>GCC 3.4</td>
<td class="compatos">GCC 4.x<br>GCC 3.4</td>
<td class="compatos">GCC 4.x<br>GCC 3.4</td>
<td class="compatos">GCC 4.2+</td>
<td class="compatos">GCC 4.2+</td>
<td class="compatos">XCode 5.0+<br>Clang</td>
<td class="compatos">MSVC, MSVC/EE<br>WinSDK<br>MinGW, Cygwin</td>
</tr>
<tr class="even">
<td class="compatcpu">x64 (64 bit)</td>
<td class="compatos">GCC 4.x</td>
<td class="compatos compatno">&nbsp;</td>
<td class="compatos">GCC 4.x</td>
<td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0</td>
<td class="compatos">GCC 4.2+</td>
<td class="compatos">ORBIS (<a href="#ps4">PS4</a>)</td>
<td class="compatos">XCode 5.0+<br>Clang</td>
<td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0<br>Durango (<a href="#xboxone">Xbox One</a>)</td>
</tr>
<tr class="odd">
<td class="compatcpu"><a href="#cross2">ARMv5+<br>ARM9E+</a></td>
<td class="compatos">GCC 4.2+</td>
<td class="compatos">GCC 4.2+</td>
<td class="compatos">GCC 4.2+</td>
<td class="compatos">GCC 4.2+<br>PSP2 (<a href="#psvita">PS VITA</a>)</td>
<td class="compatos">XCode 5.0+<br>Clang</td>
<td class="compatos compatno">&nbsp;</td>
</tr>
<tr class="even">
<td class="compatcpu"><a href="#cross2">ARM64</a></td>
<td class="compatos">GCC 4.8+</td>
<td class="compatos compatno">&nbsp;</td>
<td class="compatos">XCode 6.0+<br>Clang 3.5+</td>
<td class="compatos compatno">&nbsp;</td>
</tr>
<tr class="odd">
<td class="compatcpu"><a href="#cross2">PPC</a></td>
<td class="compatos">GCC 4.3+</td>
<td class="compatos">GCC 4.3+<br>GCC 4.1 (<a href="#ps3">PS3</a>)</td>
<td class="compatos compatno">&nbsp;</td>
<td class="compatos">XEDK (<a href="#xbox360">Xbox 360</a>)</td>
</tr>
<tr class="odd">
<td class="compatcpu"><a href="#cross2">PPC/e500v2</a></td>
<td class="compatos">GCC 4.3+</td>
<td class="compatos">GCC 4.3+</td>
<td class="compatos compatno">&nbsp;</td>
<td class="compatos compatno">&nbsp;</td>
</tr>
<tr class="even">
<td class="compatcpu"><a href="#cross2">MIPS</a></td>
<td class="compatos">GCC 4.3+</td>
@@ -188,8 +190,8 @@ open a terminal window and change to this directory. Now unpack the archive
and change to the newly created directory:
</p>
<pre class="code">
tar zxf LuaJIT-2.0.1.tar.gz
cd LuaJIT-2.0.1</pre>
tar zxf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4</pre>
<h3>Building LuaJIT</h3>
<p>
The supplied Makefiles try to auto-detect the settings needed for your
@@ -383,10 +385,11 @@ make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
# ARM hard-float ABI with VFP (armhf, requires recent toolchain)
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
# ARM64 (requires x64 host)
make CROSS=aarch64-linux-
# PPC
make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
# PPC/e500v2 (fast interpreter only)
make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe-
# MIPS big-endian
make HOST_CC="gcc -m32" CROSS=mips-linux-
@@ -439,8 +442,7 @@ NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86"
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
</pre>
<p>
You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="http://developer.apple.com/devcenter/ios/index.action"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>.
The environment variables need to match the iOS SDK version:
You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="http://developer.apple.com/devcenter/ios/index.action"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>:
</p>
<p style="font-size: 8pt;">
Note: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps
@@ -450,38 +452,84 @@ much slower than the JIT compiler. Please complain to Apple, not me.
Or use Android. :-p
</p>
<pre class="code">
IXCODE=`xcode-select -print-path`
ISDK=$IXCODE/Platforms/iPhoneOS.platform/Developer
ISDKVER=iPhoneOS6.0.sdk
ISDKP=$ISDK/usr/bin/
ISDKF="-arch armv7 -isysroot $ISDK/SDKs/$ISDKVER"
make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP TARGET_FLAGS="$ISDKF" \
TARGET_SYS=iOS
# iOS/ARM (32 bit)
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
ICC=$(xcrun --sdk iphoneos --find clang)
ISDKF="-arch armv7 -isysroot $ISDKP"
make HOST_CC="clang -m32 -arch i386" CROSS="$(dirname $ICC)/" \
TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
# iOS/ARM64
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
ICC=$(xcrun --sdk iphoneos --find clang)
ISDKF="-arch arm64 -isysroot $ISDKP"
make CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
</pre>
<h3 id="consoles">Cross-compiling for consoles</h3>
<p>
You can cross-compile for <b id="ps3">PS3</b> using the PS3&nbsp;SDK from
a Linux host or a Windows host (requires 32 bit MinGW (GCC) on the host,
too). Due to restrictions on consoles, the JIT compiler is disabled and
only the fast interpreter is built:
Building LuaJIT for consoles requires both a supported host compiler
(x86 or x64) and a cross-compiler (to PPC or ARM) from the official
console SDK.
</p>
<p>
Due to restrictions on consoles, the JIT compiler is disabled and only
the fast interpreter is built. This is still faster than plain Lua,
but much slower than the JIT compiler. The FFI is disabled, too, since
it's not very useful in such an environment.
</p>
<p>
The following commands build a static library <tt>libluajit.a</tt>,
which can be linked against your game, just like the Lua library.
</p>
<p>
To cross-compile for <b id="ps3">PS3</b> from a Linux host (requires
32&nbsp;bit GCC, i.e. multilib Linux/x64) or a Windows host (requires
32&nbsp;bit MinGW), run this command:
</p>
<pre class="code">
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
</pre>
<p>
You can cross-compile for <b id="xbox360">Xbox 360</b> using the
Xbox&nbsp;360 SDK (MSVC + XEDK). Due to restrictions on consoles, the
JIT compiler is disabled and only the fast interpreter is built.
To cross-compile for <b id="ps4">PS4</b> from a Windows host,
open a "Visual Studio .NET Command Prompt" (64&nbsp;bit host compiler),
<tt>cd</tt> to the directory where you've unpacked the sources and
run the following commands:
</p>
<pre class="code">
cd src
ps4build
</pre>
<p>
Open a "Visual Studio .NET Command Prompt" (32&nbsp;bit host compiler),
To cross-compile for <b id="psvita">PS Vita</b> from a Windows host,
open a "Visual Studio .NET Command Prompt" (32&nbsp;bit host compiler),
<tt>cd</tt> to the directory where you've unpacked the sources and
run the following commands:
</p>
<pre class="code">
cd src
psvitabuild
</pre>
<p>
To cross-compile for <b id="xbox360">Xbox 360</b> from a Windows host,
open a "Visual Studio .NET Command Prompt" (32&nbsp;bit host compiler),
<tt>cd</tt> to the directory where you've unpacked the sources and run
the following commands. This builds a static library <tt>luajit20.lib</tt>,
which can be linked against your game, just like the Lua library.
the following commands:
</p>
<pre class="code">
cd src
xedkbuild
</pre>
<p>
To cross-compile for <b id="xboxone">Xbox One</b> from a Windows host,
open a "Visual Studio .NET Command Prompt" (64&nbsp;bit host compiler),
<tt>cd</tt> to the directory where you've unpacked the sources and run
the following commands:
</p>
<pre class="code">
cd src
xb1build
</pre>
<h2 id="embed">Embedding LuaJIT</h2>
<p>
@@ -565,9 +613,11 @@ for a regular distribution build:
<ul>
<li><tt>PREFIX</tt> overrides the installation path and should usually
be set to <tt>/usr</tt>. Setting this also changes the module paths and
the <tt>-rpath</tt> of the shared library.</li>
the paths needed to locate the shared library.</li>
<li><tt>DESTDIR</tt> is an absolute path which allows you to install
to a shadow tree instead of the root tree of the build system.</li>
<li><tt>MULTILIB</tt> sets the architecture-specific library path component
for multilib systems. The default is <tt>lib</tt>.</li>
<li>Have a look at the top-level <tt>Makefile</tt> and <tt>src/Makefile</tt>
for additional variables to tweak. The following variables <em>may</em> be
overridden, but it's <em>not</em> recommended, except for special needs
@@ -603,7 +653,7 @@ to me (the upstream) and not you (the package maintainer), anyway.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>LuaJIT</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -38,6 +38,9 @@ table.os1 td {
table.os2 td {
color: #ffa040;
}
table.os3 td {
color: #40ffff;
}
table.compiler td {
color: #2080ff;
background: #62bf41;
@@ -123,6 +126,8 @@ table.feature small {
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -147,7 +152,7 @@ Lua is a powerful, dynamic and light-weight programming language.
It may be embedded or used as a general-purpose, stand-alone language.
</p>
<p>
LuaJIT is Copyright &copy; 2005-2013 Mike Pall, released under the
LuaJIT is Copyright &copy; 2005-2015 Mike Pall, released under the
<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT open source license</a>.
</p>
<p>
@@ -158,13 +163,16 @@ LuaJIT is Copyright &copy; 2005-2013 Mike Pall, released under the
<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>OSX</td><td>POSIX</td></tr>
</table>
<table class="feature os os2">
<tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td><td>PS3</td><td>Xbox 360</td></tr>
<tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td></tr>
</table>
<table class="feature os os3">
<tr><td>PS3</td><td>PS4</td><td>PS Vita</td><td>Xbox 360</td><td>Xbox One</td></tr>
</table>
<table class="feature compiler">
<tr><td>GCC</td><td>CLANG<br>LLVM</td><td>MSVC</td></tr>
</table>
<table class="feature cpu">
<tr><td>x86</td><td>x64</td><td>ARM</td><td>PPC</td><td>e500</td><td>MIPS</td></tr>
<tr><td>x86</td><td>x64</td><td>ARM</td><td>ARM64</td><td>PPC</td><td>MIPS</td></tr>
</table>
<table class="feature fcompat">
<tr><td>Lua&nbsp;5.1<br>API+ABI</td><td>+&nbsp;JIT</td><td>+&nbsp;BitOp</td><td>+&nbsp;FFI</td><td>Drop-in<br>DLL/.so</td></tr>
@@ -218,7 +226,7 @@ Please select a sub-topic in the navigation bar to learn more about LuaJIT.
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -4,7 +4,7 @@
<title>Running LuaJIT</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -63,6 +63,8 @@ td.param_default {
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
@@ -178,6 +180,7 @@ Here are the available LuaJIT control commands:
<li id="j_flush"><tt>-jflush</tt> &mdash; Flushes the whole cache of compiled code.</li>
<li id="j_v"><tt>-jv</tt> &mdash; Shows verbose information about the progress of the JIT compiler.</li>
<li id="j_dump"><tt>-jdump</tt> &mdash; Dumps the code and structures used in various compiler stages.</li>
<li id="j_p"><tt>-jp</tt> &mdash; Start the <a href="ext_profiler.html">integrated profiler</a>.</li>
</ul>
<p>
The <tt>-jv</tt> and <tt>-jdump</tt> commands are extension modules
@@ -186,7 +189,7 @@ itself. For a description of their options and output format, please
read the comment block at the start of their source.
They can be found in the <tt>lib</tt> directory of the source
distribution or installed under the <tt>jit</tt> directory. By default
this is <tt>/usr/local/share/luajit-2.0.1/jit</tt> on POSIX
this is <tt>/usr/local/share/luajit-2.0.4/jit</tt> on POSIX
systems.
</p>
@@ -296,7 +299,7 @@ Here are the parameters and their default settings:
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -1,10 +1,10 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Status &amp; Roadmap</title>
<title>Status</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2013, Mike Pall">
<meta name="Copyright" content="Copyright (C) 2005-2015, Mike Pall">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -17,7 +17,7 @@ ul li { padding-bottom: 0.3em; }
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1>Status &amp; Roadmap</h1>
<h1>Status</h1>
</div>
<div id="nav">
<ul><li>
@@ -44,6 +44,8 @@ ul li { padding-bottom: 0.3em; }
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a class="current" href="status.html">Status</a>
@@ -102,20 +104,11 @@ handled correctly. The error may fall through an on-trace
garbage collector.
</li>
</ul>
<h2>Roadmap</h2>
<p>
Please refer to the
<a href="http://www.freelists.org/post/luajit/LuaJIT-Roadmap-20122013"><span class="ext">&raquo;</span>&nbsp;LuaJIT Roadmap 2012/2013</a> and an
<a href="http://www.freelists.org/post/luajit/LuaJIT-Roadmap-20122013-UPDATE"><span class="ext">&raquo;</span>&nbsp;update on release planning</a> for details.
</p>
<p>
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright &copy; 2005-2013 Mike Pall
Copyright &copy; 2005-2015 Mike Pall
<span class="noprint">
&middot;
<a href="contact.html">Contact</a>
@@ -1,6 +1,6 @@
/*
** DynASM ARM encoding engine.
** Copyright (C) 2005-2013 Mike Pall. All rights reserved.
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
@@ -211,7 +211,8 @@ void dasm_put(Dst_DECL, int start, ...)
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
if (n >= 0) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
@@ -1,7 +1,7 @@
------------------------------------------------------------------------------
-- DynASM ARM module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
@@ -9,9 +9,9 @@
local _info = {
arch = "arm",
description = "DynASM ARM module",
version = "1.3.0",
vernum = 10300,
release = "2011-05-05",
version = "1.4.0",
vernum = 10400,
release = "2015-10-18",
author = "Mike Pall",
license = "MIT",
}
@@ -923,19 +923,22 @@ local function parse_template(params, template, nparams, pos)
end
map_op[".template__"] = function(params, template, nparams)
if not params then return sub(template, 9) end
if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end
-- Limit number of section buffer positions used by a single dasm_put().
-- A single opcode needs a maximum of 3 positions.
if secpos+3 > maxsecpos then wflush() end
local pos = wpos()
local apos, spos = #actargs, secpos
local lpos, apos, spos = #actlist, #actargs, secpos
local ok, err
for t in gmatch(template, "[^|]+") do
ok, err = pcall(parse_template, params, t, nparams, pos)
if ok then return end
secpos = spos
actlist[lpos+1] = nil
actlist[lpos+2] = nil
actlist[lpos+3] = nil
actargs[apos+1] = nil
actargs[apos+2] = nil
actargs[apos+3] = nil
+518
View File
@@ -0,0 +1,518 @@
/*
** DynASM ARM64 encoding engine.
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define DASM_ARCH "arm64"
#ifndef DASM_EXTERN
#define DASM_EXTERN(a,b,c,d) 0
#endif
/* Action definitions. */
enum {
DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
/* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC,
DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
DASM__MAX
};
/* Maximum number of section buffer positions for a single dasm_put() call. */
#define DASM_MAXSECPOS 25
/* DynASM encoder status codes. Action list offset or number are or'ed in. */
#define DASM_S_OK 0x00000000
#define DASM_S_NOMEM 0x01000000
#define DASM_S_PHASE 0x02000000
#define DASM_S_MATCH_SEC 0x03000000
#define DASM_S_RANGE_I 0x11000000
#define DASM_S_RANGE_SEC 0x12000000
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_REL 0x15000000
#define DASM_S_UNDEF_LG 0x21000000
#define DASM_S_UNDEF_PC 0x22000000
/* Macros to convert positions (8 bit section + 24 bit index). */
#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
#define DASM_SEC2POS(sec) ((sec)<<24)
#define DASM_POS2SEC(pos) ((pos)>>24)
#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
/* Action list type. */
typedef const unsigned int *dasm_ActList;
/* Per-section structure. */
typedef struct dasm_Section {
int *rbuf; /* Biased buffer pointer (negative section bias). */
int *buf; /* True buffer pointer. */
size_t bsize; /* Buffer size in bytes. */
int pos; /* Biased buffer position. */
int epos; /* End of biased buffer position - max single put. */
int ofs; /* Byte offset into section. */
} dasm_Section;
/* Core structure holding the DynASM encoding state. */
struct dasm_State {
size_t psize; /* Allocated size of this structure. */
dasm_ActList actionlist; /* Current actionlist pointer. */
int *lglabels; /* Local/global chain/pos ptrs. */
size_t lgsize;
int *pclabels; /* PC label chains/pos ptrs. */
size_t pcsize;
void **globals; /* Array of globals (bias -10). */
dasm_Section *section; /* Pointer to active section. */
size_t codesize; /* Total size of all code sections. */
int maxsection; /* 0 <= sectionidx < maxsection. */
int status; /* Status code. */
dasm_Section sections[1]; /* All sections. Alloc-extended. */
};
/* The size of the core structure depends on the max. number of sections. */
#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
/* Initialize DynASM state. */
void dasm_init(Dst_DECL, int maxsection)
{
dasm_State *D;
size_t psz = 0;
int i;
Dst_REF = NULL;
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
D = Dst_REF;
D->psize = psz;
D->lglabels = NULL;
D->lgsize = 0;
D->pclabels = NULL;
D->pcsize = 0;
D->globals = NULL;
D->maxsection = maxsection;
for (i = 0; i < maxsection; i++) {
D->sections[i].buf = NULL; /* Need this for pass3. */
D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
D->sections[i].bsize = 0;
D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
}
}
/* Free DynASM state. */
void dasm_free(Dst_DECL)
{
dasm_State *D = Dst_REF;
int i;
for (i = 0; i < D->maxsection; i++)
if (D->sections[i].buf)
DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
DASM_M_FREE(Dst, D, D->psize);
}
/* Setup global label array. Must be called before dasm_setup(). */
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
{
dasm_State *D = Dst_REF;
D->globals = gl - 10; /* Negative bias to compensate for locals. */
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
}
/* Grow PC label array. Can be called after dasm_setup(), too. */
void dasm_growpc(Dst_DECL, unsigned int maxpc)
{
dasm_State *D = Dst_REF;
size_t osz = D->pcsize;
DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
}
/* Setup encoder. */
void dasm_setup(Dst_DECL, const void *actionlist)
{
dasm_State *D = Dst_REF;
int i;
D->actionlist = (dasm_ActList)actionlist;
D->status = DASM_S_OK;
D->section = &D->sections[0];
memset((void *)D->lglabels, 0, D->lgsize);
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
for (i = 0; i < D->maxsection; i++) {
D->sections[i].pos = DASM_SEC2POS(i);
D->sections[i].ofs = 0;
}
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) { \
D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
#define CKPL(kind, st) \
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
#else
#define CK(x, st) ((void)0)
#define CKPL(kind, st) ((void)0)
#endif
static int dasm_imm12(unsigned int n)
{
if ((n >> 12) == 0)
return n;
else if ((n & 0xff000fff) == 0)
return (n >> 12) | 0x1000;
else
return -1;
}
static int dasm_ffs(unsigned long long x)
{
int n = -1;
while (x) { x >>= 1; n++; }
return n;
}
static int dasm_imm13(int lo, int hi)
{
int inv = 0, w = 64, s = 0xfff, xa, xb;
unsigned long long n = (((unsigned long long)hi) << 32) | (unsigned int)lo;
unsigned long long m = 1ULL, a, b, c;
if (n & 1) { n = ~n; inv = 1; }
a = n & -n; b = (n+a)&-(n+a); c = (n+a-b)&-(n+a-b);
xa = dasm_ffs(a); xb = dasm_ffs(b);
if (c) {
w = dasm_ffs(c) - xa;
if (w == 32) m = 0x0000000100000001UL;
else if (w == 16) m = 0x0001000100010001UL;
else if (w == 8) m = 0x0101010101010101UL;
else if (w == 4) m = 0x1111111111111111UL;
else if (w == 2) m = 0x5555555555555555UL;
else return -1;
s = (-2*w & 0x3f) - 1;
} else if (!a) {
return -1;
} else if (xb == -1) {
xb = 64;
}
if ((b-a) * m != n) return -1;
if (inv) {
return ((w - xb) << 6) | (s+w+xa-xb);
} else {
return ((w - xa) << 6) | (s+xb-xa);
}
return -1;
}
/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
void dasm_put(Dst_DECL, int start, ...)
{
va_list ap;
dasm_State *D = Dst_REF;
dasm_ActList p = D->actionlist + start;
dasm_Section *sec = D->section;
int pos = sec->pos, ofs = sec->ofs;
int *b;
if (pos >= sec->epos) {
DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
}
b = sec->rbuf;
b[pos++] = start;
va_start(ap, start);
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
if (action >= DASM__MAX) {
ofs += 4;
} else {
int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
switch (action) {
case DASM_STOP: goto stop;
case DASM_SECTION:
n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
D->section = &D->sections[n]; goto stop;
case DASM_ESC: p++; ofs += 4; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
case DASM_REL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putrel:
n = *pl;
if (n < 0) { /* Label exists. Get label pos and store it. */
b[pos] = -n;
} else {
linkrel:
b[pos] = n; /* Else link to rel chain, anchored at label. */
*pl = pos;
}
pos++;
break;
case DASM_LABEL_LG:
pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
case DASM_LABEL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putlabel:
n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
}
*pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_IMM:
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
n >>= ((ins>>10)&31);
#ifdef DASM_CHECKS
if ((ins & 0x8000))
CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
else
CK((n>>((ins>>5)&31)) == 0, RANGE_I);
#endif
b[pos++] = n;
break;
case DASM_IMM6:
CK((n >> 6) == 0, RANGE_I);
b[pos++] = n;
break;
case DASM_IMM12:
CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
b[pos++] = n;
break;
case DASM_IMM13W:
CK(dasm_imm13(n, n) != -1, RANGE_I);
b[pos++] = n;
break;
case DASM_IMM13X: {
int m = va_arg(ap, int);
CK(dasm_imm13(n, m) != -1, RANGE_I);
b[pos++] = n;
b[pos++] = m;
break;
}
case DASM_IMML: {
#ifdef DASM_CHECKS
int scale = (p[-2] >> 30);
CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
(unsigned int)(n+256) < 512, RANGE_I);
#endif
b[pos++] = n;
break;
}
}
}
}
stop:
va_end(ap);
sec->pos = pos;
sec->ofs = ofs;
}
#undef CK
/* Pass 2: Link sections, shrink aligns, fix label offsets. */
int dasm_link(Dst_DECL, size_t *szp)
{
dasm_State *D = Dst_REF;
int secnum;
int ofs = 0;
#ifdef DASM_CHECKS
*szp = 0;
if (D->status != DASM_S_OK) return D->status;
{
int pc;
for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
}
#endif
{ /* Handle globals not defined in this translation unit. */
int idx;
for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
int n = D->lglabels[idx];
/* Undefined label: Collapse rel chain and replace with marker (< 0). */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
}
}
/* Combine all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->rbuf;
int pos = DASM_SEC2POS(secnum);
int lastpos = sec->pos;
while (pos != lastpos) {
dasm_ActList p = D->actionlist + b[pos++];
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: p++; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
case DASM_IMML: pos++; break;
case DASM_IMM13X: pos += 2; break;
}
}
stop: (void)0;
}
ofs += sec->ofs; /* Next section starts right after current section. */
}
D->codesize = ofs; /* Total size of all code sections */
*szp = ofs;
return DASM_S_OK;
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
#else
#define CK(x, st) ((void)0)
#endif
/* Pass 3: Encode sections. */
int dasm_encode(Dst_DECL, void *buffer)
{
dasm_State *D = Dst_REF;
char *base = (char *)buffer;
unsigned int *cp = (unsigned int *)buffer;
int secnum;
/* Encode all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->buf;
int *endb = sec->rbuf + sec->pos;
while (b != endb) {
dasm_ActList p = D->actionlist + *b++;
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: *cp++ = *p++; break;
case DASM_REL_EXT:
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
goto patchrel;
case DASM_ALIGN:
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
break;
case DASM_REL_LG:
CK(n >= 0, UNDEF_LG);
case DASM_REL_PC:
CK(n >= 0, UNDEF_PC);
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) + 4;
patchrel:
if (!(ins & 0xf800)) { /* B, BL */
CK((n & 3) == 0 && ((n+0x08000000) >> 28) == 0, RANGE_REL);
cp[-1] |= ((n >> 2) & 0x03ffffff);
} else if ((ins & 0x800)) { /* B.cond, CBZ, CBNZ, LDR* literal */
CK((n & 3) == 0 && ((n+0x00100000) >> 21) == 0, RANGE_REL);
cp[-1] |= ((n << 3) & 0x00ffffe0);
} else if ((ins & 0x3000) == 0x2000) { /* ADR */
CK(((n+0x00100000) >> 21) == 0, RANGE_REL);
cp[-1] |= ((n << 3) & 0x00ffffe0) | ((n & 3) << 29);
} else if ((ins & 0x3000) == 0x3000) { /* ADRP */
cp[-1] |= ((n >> 9) & 0x00ffffe0) | (((n >> 12) & 3) << 29);
} else if ((ins & 0x1000)) { /* TBZ, TBNZ */
CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL);
cp[-1] |= ((n << 3) & 0x0007ffe0);
}
break;
case DASM_LABEL_LG:
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
break;
case DASM_LABEL_PC: break;
case DASM_IMM:
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
case DASM_IMM6:
cp[-1] |= ((n&31) << 19) | ((n&32) << 26);
break;
case DASM_IMM12:
cp[-1] |= (dasm_imm12((unsigned int)n) << 10);
break;
case DASM_IMM13W:
cp[-1] |= (dasm_imm13(n, n) << 10);
break;
case DASM_IMM13X:
cp[-1] |= (dasm_imm13(n, *b++) << 10);
break;
case DASM_IMML: {
int scale = (p[-2] >> 30);
cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
break;
}
default: *cp++ = ins; break;
}
}
stop: (void)0;
}
}
if (base + D->codesize != (char *)cp) /* Check for phase errors. */
return DASM_S_PHASE;
return DASM_S_OK;
}
#undef CK
/* Get PC label offset. */
int dasm_getpclabel(Dst_DECL, unsigned int pc)
{
dasm_State *D = Dst_REF;
if (pc*sizeof(int) < D->pcsize) {
int pos = D->pclabels[pc];
if (pos < 0) return *DASM_POS2PTR(D, -pos);
if (pos > 0) return -1; /* Undefined. */
}
return -2; /* Unused or out of range. */
}
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
int dasm_checkstep(Dst_DECL, int secmatch)
{
dasm_State *D = Dst_REF;
if (D->status == DASM_S_OK) {
int i;
for (i = 1; i <= 9; i++) {
if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
D->lglabels[i] = 0;
}
}
if (D->status == DASM_S_OK && secmatch >= 0 &&
D->section != &D->sections[secmatch])
D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
return D->status;
}
#endif
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/*
** DynASM MIPS encoding engine.
** Copyright (C) 2005-2013 Mike Pall. All rights reserved.
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
@@ -202,7 +202,8 @@ void dasm_put(Dst_DECL, int start, ...)
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
if (n >= 0) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
@@ -1,7 +1,7 @@
------------------------------------------------------------------------------
-- DynASM MIPS module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
@@ -9,9 +9,9 @@
local _info = {
arch = "mips",
description = "DynASM MIPS module",
version = "1.3.0",
vernum = 10300,
release = "2012-01-23",
version = "1.4.0",
vernum = 10400,
release = "2015-10-18",
author = "Mike Pall",
license = "MIT",
}
@@ -1,6 +1,6 @@
/*
** DynASM PPC encoding engine.
** Copyright (C) 2005-2013 Mike Pall. All rights reserved.
** DynASM PPC/PPC64 encoding engine.
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
@@ -21,7 +21,7 @@ enum {
/* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMSH,
DASM__MAX
};
@@ -202,7 +202,8 @@ void dasm_put(Dst_DECL, int start, ...)
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
if (n >= 0) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
@@ -243,6 +244,10 @@ void dasm_put(Dst_DECL, int start, ...)
#endif
b[pos++] = n;
break;
case DASM_IMMSH:
CK((n >> 6) == 0, RANGE_I);
b[pos++] = n;
break;
}
}
}
@@ -298,7 +303,7 @@ int dasm_link(Dst_DECL, size_t *szp)
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: pos++; break;
case DASM_IMM: case DASM_IMMSH: pos++; break;
}
}
stop: (void)0;
@@ -365,6 +370,9 @@ int dasm_encode(Dst_DECL, void *buffer)
case DASM_IMM:
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
case DASM_IMMSH:
cp[-1] |= (ins & 1) ? ((n&31)<<11)|((n&32)>>4) : ((n&31)<<6)|(n&32);
break;
default: *cp++ = ins; break;
}
}
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/*
** DynASM encoding engine prototypes.
** Copyright (C) 2005-2013 Mike Pall. All rights reserved.
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
@@ -10,8 +10,8 @@
#include <stddef.h>
#include <stdarg.h>
#define DASM_IDENT "DynASM 1.3.0"
#define DASM_VERSION 10300 /* 1.3.0 */
#define DASM_IDENT "DynASM 1.4.0"
#define DASM_VERSION 10400 /* 1.4.0 */
#ifndef Dst_DECL
#define Dst_DECL dasm_State **Dst
@@ -1,7 +1,7 @@
------------------------------------------------------------------------------
-- DynASM x64 module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
-- This module just sets 64 bit mode for the combined x86/x64 module.
@@ -1,6 +1,6 @@
/*
** DynASM x86 encoding engine.
** Copyright (C) 2005-2013 Mike Pall. All rights reserved.
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
@@ -213,7 +213,8 @@ void dasm_put(Dst_DECL, int start, ...)
case DASM_REL_LG:
case DASM_IMM_LG:
n = *p++; pl = D->lglabels + n;
if (n <= 246) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
/* Bkwd rel or global. */
if (n <= 246) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl -= 246; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
@@ -390,7 +391,12 @@ int dasm_encode(Dst_DECL, void *buffer)
case DASM_IMM_D: wd: dasmd(n); break;
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
case DASM_IMM_W: dasmw(n); break;
case DASM_VREG: { int t = *p++; if (t >= 2) n<<=3; cp[-1] |= n; break; }
case DASM_VREG: {
int t = *p++;
if (t >= 5) n <<= 4; else if (t >= 2) n <<= 3;
cp[-1] ^= n;
break;
}
case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
b++; n = (int)(ptrdiff_t)D->globals[-n];
case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
@@ -1,7 +1,7 @@
------------------------------------------------------------------------------
-- DynASM x86/x64 module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
@@ -11,9 +11,9 @@ local x64 = x64
local _info = {
arch = x64 and "x64" or "x86",
description = "DynASM x86/x64 module",
version = "1.3.0",
vernum = 10300,
release = "2011-05-05",
version = "1.4.0",
vernum = 10400,
release = "2015-10-18",
author = "Mike Pall",
license = "MIT",
}
@@ -27,9 +27,9 @@ local assert, unpack, setmetatable = assert, unpack or table.unpack, setmetatabl
local _s = string
local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
local concat, sort = table.concat, table.sort
local concat, sort, remove = table.concat, table.sort, table.remove
local bit = bit or require("bit")
local band, shl, shr = bit.band, bit.lshift, bit.rshift
local band, bxor, shl, shr = bit.band, bit.bxor, bit.lshift, bit.rshift
-- Inherited tables and callbacks.
local g_opt, g_arch
@@ -299,7 +299,7 @@ local function mkrmap(sz, cl, names)
local iname = format("@%s%x%s", sz, i, needrex and "R" or "")
if needrex then map_reg_needrex[iname] = true end
local name
if sz == "o" then name = format("xmm%d", i)
if sz == "o" or sz == "y" then name = format("%s%d", cl, i)
elseif sz == "f" then name = format("st%d", i)
else name = format("r%d%s", i, sz == addrsize and "" or sz) end
map_archdef[name] = iname
@@ -334,21 +334,24 @@ mkrmap("f", "Rf")
-- SSE registers (oword sized, but qword and dword accessible).
mkrmap("o", "xmm")
-- AVX registers (yword sized, but oword, qword and dword accessible).
mkrmap("y", "ymm")
-- Operand size prefixes to codes.
local map_opsize = {
byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
aword = addrsize,
byte = "b", word = "w", dword = "d", qword = "q", oword = "o", yword = "y",
tword = "t", aword = addrsize,
}
-- Operand size code to number.
local map_opsizenum = {
b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
b = 1, w = 2, d = 4, q = 8, o = 16, y = 32, t = 10,
}
-- Operand size code to name.
local map_opsizename = {
b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
f = "fpword",
b = "byte", w = "word", d = "dword", q = "qword", o = "oword", y = "yword",
t = "tword", f = "fpword",
}
-- Valid index register scale factors.
@@ -460,7 +463,29 @@ local function wputszarg(sz, n)
end
-- Put multi-byte opcode with operand-size dependent modifications.
local function wputop(sz, op, rex)
local function wputop(sz, op, rex, vex)
if vex then
local tail
if vex.m == 1 and band(rex, 11) == 0 then
wputb(0xc5)
tail = shl(bxor(band(rex, 4), 4), 5)
else
wputb(0xc4)
wputb(shl(bxor(band(rex, 7), 7), 5) + vex.m)
tail = shl(band(rex, 8), 4)
end
local reg, vreg = 0, nil
if vex.v then
reg = vex.v.reg
if not reg then werror("bad vex operand") end
if reg < 0 then reg = 0; vreg = vex.v.vreg end
end
if sz == "y" or vex.l then tail = tail + 4 end
wputb(tail + shl(bxor(reg, 15), 3) + vex.p)
if vreg then waction("VREG", vreg); wputxb(4) end
rex = 0
if op >= 256 then werror("bad vex opcode") end
end
local r
if rex ~= 0 and not x64 then werror("bad operand size") end
if sz == "w" then wputb(102) end
@@ -881,9 +906,15 @@ end
-- "m"/"M" generates ModRM/SIB from the 1st/2nd operand.
-- The spare 3 bits are either filled with the last hex digit or
-- the result from a previous "r"/"R". The opcode is restored.
-- "u" Use VEX encoding, vvvv unused.
-- "v"/"V" Use VEX encoding, vvvv from 1st/2nd operand (the operand is
-- removed from the list used by future characters).
-- "L" Force VEX.L
--
-- All of the following characters force a flush of the opcode:
-- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand.
-- "s" stores a 4 bit immediate from the last register operand,
-- followed by 4 zero bits.
-- "S" stores a signed 8 bit immediate from the last operand.
-- "U" stores an unsigned 8 bit immediate from the last operand.
-- "W" stores an unsigned 16 bit immediate from the last operand.
@@ -1040,7 +1071,7 @@ local map_op = {
-- ED: *in Rdw,dx
-- EE: *out dx,Rb
-- EF: *out dx,Rdw
-- F0: *lock
lock_0 = "F0",
int1_0 = "F1",
repne_0 = "F2",
repnz_0 = "F2",
@@ -1081,7 +1112,11 @@ local map_op = {
btr_2 = "mrqdw:0FB3Rm|miqdw:0FBA6mU",
bts_2 = "mrqdw:0FABRm|miqdw:0FBA5mU",
shld_3 = "mriqdw:0FA4RmU|mrC/qq:0FA5Rm|mrC/dd:|mrC/ww:",
shrd_3 = "mriqdw:0FACRmU|mrC/qq:0FADRm|mrC/dd:|mrC/ww:",
rdtsc_0 = "0F31", -- P1+
rdpmc_0 = "0F33", -- P6+
cpuid_0 = "0FA2", -- P1+
-- floating point ops
@@ -1114,6 +1149,9 @@ local map_op = {
fucompp_0 = "DAE9",
fcompp_0 = "DED9",
fldenv_1 = "x.:D94m",
fnstenv_1 = "x.:D96m",
fstenv_1 = "x.:9BD96m",
fldcw_1 = "xw:nD95m",
fstcw_1 = "xw:n9BD97m",
fnstcw_1 = "xw:nD97m",
@@ -1184,11 +1222,13 @@ local map_op = {
cvtsi2sd_2 = "rm/od:F20F2ArM|rm/oq:F20F2ArXM",
cvtsi2ss_2 = "rm/od:F30F2ArM|rm/oq:F30F2ArXM",
cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
cvtss2si_2 = "rr/do:F20F2CrM|rr/qo:|rxd:|rx/qd:",
cvtss2si_2 = "rr/do:F30F2DrM|rr/qo:|rxd:|rx/qd:",
cvttpd2dq_2 = "rmo:660FE6rM",
cvttps2dq_2 = "rmo:F30F5BrM",
cvttsd2si_2 = "rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:",
cvttss2si_2 = "rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:",
fxsave_1 = "x.:0FAE0m",
fxrstor_1 = "x.:0FAE1m",
ldmxcsr_1 = "xd:0FAE2m",
lfence_0 = "0FAEE8",
maskmovdqu_2 = "rro:660FF7rM",
@@ -1217,46 +1257,14 @@ local map_op = {
movups_2 = "rmo:0F10rM|mro:0F11Rm",
orpd_2 = "rmo:660F56rM",
orps_2 = "rmo:0F56rM",
packssdw_2 = "rmo:660F6BrM",
packsswb_2 = "rmo:660F63rM",
packuswb_2 = "rmo:660F67rM",
paddb_2 = "rmo:660FFCrM",
paddd_2 = "rmo:660FFErM",
paddq_2 = "rmo:660FD4rM",
paddsb_2 = "rmo:660FECrM",
paddsw_2 = "rmo:660FEDrM",
paddusb_2 = "rmo:660FDCrM",
paddusw_2 = "rmo:660FDDrM",
paddw_2 = "rmo:660FFDrM",
pand_2 = "rmo:660FDBrM",
pandn_2 = "rmo:660FDFrM",
pause_0 = "F390",
pavgb_2 = "rmo:660FE0rM",
pavgw_2 = "rmo:660FE3rM",
pcmpeqb_2 = "rmo:660F74rM",
pcmpeqd_2 = "rmo:660F76rM",
pcmpeqw_2 = "rmo:660F75rM",
pcmpgtb_2 = "rmo:660F64rM",
pcmpgtd_2 = "rmo:660F66rM",
pcmpgtw_2 = "rmo:660F65rM",
pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nrMU", -- Mem op: SSE4.1 only.
pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nRmU", -- Mem op: SSE4.1 only.
pinsrw_3 = "rri/od:660FC4rMU|rxi/ow:",
pmaddwd_2 = "rmo:660FF5rM",
pmaxsw_2 = "rmo:660FEErM",
pmaxub_2 = "rmo:660FDErM",
pminsw_2 = "rmo:660FEArM",
pminub_2 = "rmo:660FDArM",
pmovmskb_2 = "rr/do:660FD7rM",
pmulhuw_2 = "rmo:660FE4rM",
pmulhw_2 = "rmo:660FE5rM",
pmullw_2 = "rmo:660FD5rM",
pmuludq_2 = "rmo:660FF4rM",
por_2 = "rmo:660FEBrM",
prefetchnta_1 = "xb:n0F180m",
prefetcht0_1 = "xb:n0F181m",
prefetcht1_1 = "xb:n0F182m",
prefetcht2_1 = "xb:n0F183m",
psadbw_2 = "rmo:660FF6rM",
pshufd_3 = "rmio:660F70rMU",
pshufhw_3 = "rmio:F30F70rMU",
pshuflw_3 = "rmio:F20F70rMU",
@@ -1270,23 +1278,6 @@ local map_op = {
psrldq_2 = "rio:660F733mU",
psrlq_2 = "rmo:660FD3rM|rio:660F732mU",
psrlw_2 = "rmo:660FD1rM|rio:660F712mU",
psubb_2 = "rmo:660FF8rM",
psubd_2 = "rmo:660FFArM",
psubq_2 = "rmo:660FFBrM",
psubsb_2 = "rmo:660FE8rM",
psubsw_2 = "rmo:660FE9rM",
psubusb_2 = "rmo:660FD8rM",
psubusw_2 = "rmo:660FD9rM",
psubw_2 = "rmo:660FF9rM",
punpckhbw_2 = "rmo:660F68rM",
punpckhdq_2 = "rmo:660F6ArM",
punpckhqdq_2 = "rmo:660F6DrM",
punpckhwd_2 = "rmo:660F69rM",
punpcklbw_2 = "rmo:660F60rM",
punpckldq_2 = "rmo:660F62rM",
punpcklqdq_2 = "rmo:660F6CrM",
punpcklwd_2 = "rmo:660F61rM",
pxor_2 = "rmo:660FEFrM",
rcpps_2 = "rmo:0F53rM",
rcpss_2 = "rro:F30F53rM|rx/od:",
rsqrtps_2 = "rmo:0F52rM",
@@ -1344,7 +1335,7 @@ local map_op = {
dpps_3 = "rmio:660F3A40rMU",
extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
insertps_3 = "rrio:660F3A41rMU|rxi/od:",
movntdqa_2 = "rmo:660F382ArM",
movntdqa_2 = "rxo:660F382ArM",
mpsadbw_3 = "rmio:660F3A42rMU",
packusdw_2 = "rmo:660F382BrM",
pblendvb_3 = "rmRo:660F3810rM",
@@ -1404,6 +1395,232 @@ local map_op = {
movntsd_2 = "xr/qo:nF20F2BRm",
movntss_2 = "xr/do:F30F2BRm",
-- popcnt is also in SSE4.2
-- AES-NI
aesdec_2 = "rmo:660F38DErM",
aesdeclast_2 = "rmo:660F38DFrM",
aesenc_2 = "rmo:660F38DCrM",
aesenclast_2 = "rmo:660F38DDrM",
aesimc_2 = "rmo:660F38DBrM",
aeskeygenassist_3 = "rmio:660F3ADFrMU",
pclmulqdq_3 = "rmio:660F3A44rMU",
-- AVX FP ops
vaddsubpd_3 = "rrmoy:660FVD0rM",
vaddsubps_3 = "rrmoy:F20FVD0rM",
vandpd_3 = "rrmoy:660FV54rM",
vandps_3 = "rrmoy:0FV54rM",
vandnpd_3 = "rrmoy:660FV55rM",
vandnps_3 = "rrmoy:0FV55rM",
vblendpd_4 = "rrmioy:660F3AV0DrMU",
vblendps_4 = "rrmioy:660F3AV0CrMU",
vblendvpd_4 = "rrmroy:660F3AV4BrMs",
vblendvps_4 = "rrmroy:660F3AV4ArMs",
vbroadcastf128_2 = "rx/yo:660F38u1ArM",
vcmppd_4 = "rrmioy:660FVC2rMU",
vcmpps_4 = "rrmioy:0FVC2rMU",
vcmpsd_4 = "rrrio:F20FVC2rMU|rrxi/ooq:",
vcmpss_4 = "rrrio:F30FVC2rMU|rrxi/ood:",
vcomisd_2 = "rro:660Fu2FrM|rx/oq:",
vcomiss_2 = "rro:0Fu2FrM|rx/od:",
vcvtdq2pd_2 = "rro:F30FuE6rM|rx/oq:|rm/yo:",
vcvtdq2ps_2 = "rmoy:0Fu5BrM",
vcvtpd2dq_2 = "rmoy:F20FuE6rM",
vcvtpd2ps_2 = "rmoy:660Fu5ArM",
vcvtps2dq_2 = "rmoy:660Fu5BrM",
vcvtps2pd_2 = "rro:0Fu5ArM|rx/oq:|rm/yo:",
vcvtsd2si_2 = "rr/do:F20Fu2DrM|rx/dq:|rr/qo:|rxq:",
vcvtsd2ss_3 = "rrro:F20FV5ArM|rrx/ooq:",
vcvtsi2sd_3 = "rrm/ood:F20FV2ArM|rrm/ooq:F20FVX2ArM",
vcvtsi2ss_3 = "rrm/ood:F30FV2ArM|rrm/ooq:F30FVX2ArM",
vcvtss2sd_3 = "rrro:F30FV5ArM|rrx/ood:",
vcvtss2si_2 = "rr/do:F30Fu2DrM|rxd:|rr/qo:|rx/qd:",
vcvttpd2dq_2 = "rmo:660FuE6rM|rm/oy:660FuLE6rM",
vcvttps2dq_2 = "rmoy:F30Fu5BrM",
vcvttsd2si_2 = "rr/do:F20Fu2CrM|rx/dq:|rr/qo:|rxq:",
vcvttss2si_2 = "rr/do:F30Fu2CrM|rxd:|rr/qo:|rx/qd:",
vdppd_4 = "rrmio:660F3AV41rMU",
vdpps_4 = "rrmioy:660F3AV40rMU",
vextractf128_3 = "mri/oy:660F3AuL19RmU",
vextractps_3 = "mri/do:660F3Au17RmU",
vhaddpd_3 = "rrmoy:660FV7CrM",
vhaddps_3 = "rrmoy:F20FV7CrM",
vhsubpd_3 = "rrmoy:660FV7DrM",
vhsubps_3 = "rrmoy:F20FV7DrM",
vinsertf128_4 = "rrmi/yyo:660F3AV18rMU",
vinsertps_4 = "rrrio:660F3AV21rMU|rrxi/ood:",
vldmxcsr_1 = "xd:0FuAE2m",
vmaskmovps_3 = "rrxoy:660F38V2CrM|xrroy:660F38V2ERm",
vmaskmovpd_3 = "rrxoy:660F38V2DrM|xrroy:660F38V2FRm",
vmovapd_2 = "rmoy:660Fu28rM|mroy:660Fu29Rm",
vmovaps_2 = "rmoy:0Fu28rM|mroy:0Fu29Rm",
vmovd_2 = "rm/od:660Fu6ErM|rm/oq:660FuX6ErM|mr/do:660Fu7ERm|mr/qo:",
vmovq_2 = "rro:F30Fu7ErM|rx/oq:|xr/qo:660FuD6Rm",
vmovddup_2 = "rmy:F20Fu12rM|rro:|rx/oq:",
vmovhlps_3 = "rrro:0FV12rM",
vmovhpd_2 = "xr/qo:660Fu17Rm",
vmovhpd_3 = "rrx/ooq:660FV16rM",
vmovhps_2 = "xr/qo:0Fu17Rm",
vmovhps_3 = "rrx/ooq:0FV16rM",
vmovlhps_3 = "rrro:0FV16rM",
vmovlpd_2 = "xr/qo:660Fu13Rm",
vmovlpd_3 = "rrx/ooq:660FV12rM",
vmovlps_2 = "xr/qo:0Fu13Rm",
vmovlps_3 = "rrx/ooq:0FV12rM",
vmovmskpd_2 = "rr/do:660Fu50rM|rr/dy:660FuL50rM",
vmovmskps_2 = "rr/do:0Fu50rM|rr/dy:0FuL50rM",
vmovntpd_2 = "xroy:660Fu2BRm",
vmovntps_2 = "xroy:0Fu2BRm",
vmovsd_2 = "rx/oq:F20Fu10rM|xr/qo:F20Fu11Rm",
vmovsd_3 = "rrro:F20FV10rM",
vmovshdup_2 = "rmoy:F30Fu16rM",
vmovsldup_2 = "rmoy:F30Fu12rM",
vmovss_2 = "rx/od:F30Fu10rM|xr/do:F30Fu11Rm",
vmovss_3 = "rrro:F30FV10rM",
vmovupd_2 = "rmoy:660Fu10rM|mroy:660Fu11Rm",
vmovups_2 = "rmoy:0Fu10rM|mroy:0Fu11Rm",
vorpd_3 = "rrmoy:660FV56rM",
vorps_3 = "rrmoy:0FV56rM",
vpermilpd_3 = "rrmoy:660F38V0DrM|rmioy:660F3Au05rMU",
vpermilps_3 = "rrmoy:660F38V0CrM|rmioy:660F3Au04rMU",
vperm2f128_4 = "rrmiy:660F3AV06rMU",
vptestpd_2 = "rmoy:660F38u0FrM",
vptestps_2 = "rmoy:660F38u0ErM",
vrcpps_2 = "rmoy:0Fu53rM",
vrcpss_3 = "rrro:F30FV53rM|rrx/ood:",
vrsqrtps_2 = "rmoy:0Fu52rM",
vrsqrtss_3 = "rrro:F30FV52rM|rrx/ood:",
vroundpd_3 = "rmioy:660F3AV09rMU",
vroundps_3 = "rmioy:660F3AV08rMU",
vroundsd_4 = "rrrio:660F3AV0BrMU|rrxi/ooq:",
vroundss_4 = "rrrio:660F3AV0ArMU|rrxi/ood:",
vshufpd_4 = "rrmioy:660FVC6rMU",
vshufps_4 = "rrmioy:0FVC6rMU",
vsqrtps_2 = "rmoy:0Fu51rM",
vsqrtss_2 = "rro:F30Fu51rM|rx/od:",
vsqrtpd_2 = "rmoy:660Fu51rM",
vsqrtsd_2 = "rro:F20Fu51rM|rx/oq:",
vstmxcsr_1 = "xd:0FuAE3m",
vucomisd_2 = "rro:660Fu2ErM|rx/oq:",
vucomiss_2 = "rro:0Fu2ErM|rx/od:",
vunpckhpd_3 = "rrmoy:660FV15rM",
vunpckhps_3 = "rrmoy:0FV15rM",
vunpcklpd_3 = "rrmoy:660FV14rM",
vunpcklps_3 = "rrmoy:0FV14rM",
vxorpd_3 = "rrmoy:660FV57rM",
vxorps_3 = "rrmoy:0FV57rM",
vzeroall_0 = "0FuL77",
vzeroupper_0 = "0Fu77",
-- AVX2 FP ops
vbroadcastss_2 = "rx/od:660F38u18rM|rx/yd:|rro:|rr/yo:",
vbroadcastsd_2 = "rx/yq:660F38u19rM|rr/yo:",
-- *vgather* (!vsib)
vpermpd_3 = "rmiy:660F3AuX01rMU",
vpermps_3 = "rrmy:660F38V16rM",
-- AVX, AVX2 integer ops
-- In general, xmm requires AVX, ymm requires AVX2.
vlddqu_2 = "rxoy:F20FuF0rM",
vmaskmovdqu_2 = "rro:660FuF7rM",
vmovdqa_2 = "rmoy:660Fu6FrM|mroy:660Fu7FRm",
vmovdqu_2 = "rmoy:F30Fu6FrM|mroy:F30Fu7FRm",
vmovntdq_2 = "xroy:660FuE7Rm",
vmovntdqa_2 = "rxoy:660F38u2ArM",
vmpsadbw_4 = "rrmioy:660F3AV42rMU",
vpabsb_2 = "rmoy:660F38u1CrM",
vpabsd_2 = "rmoy:660F38u1ErM",
vpabsw_2 = "rmoy:660F38u1DrM",
vpackusdw_3 = "rrmoy:660F38V2BrM",
vpalignr_4 = "rrmioy:660F3AV0FrMU",
vpblendvb_4 = "rrmroy:660F3AV4CrMs",
vpblendw_4 = "rrmioy:660F3AV0ErMU",
vpclmulqdq_4 = "rrmio:660F3AV44rMU",
vpcmpeqq_3 = "rrmoy:660F38V29rM",
vpcmpestri_3 = "rmio:660F3Au61rMU",
vpcmpestrm_3 = "rmio:660F3Au60rMU",
vpcmpgtq_3 = "rrmoy:660F38V37rM",
vpcmpistri_3 = "rmio:660F3Au63rMU",
vpcmpistrm_3 = "rmio:660F3Au62rMU",
vpextrb_3 = "rri/do:660F3Au14nRmU|rri/qo:|xri/bo:",
vpextrw_3 = "rri/do:660FuC5rMU|xri/wo:660F3Au15nRmU",
vpextrd_3 = "mri/do:660F3Au16RmU",
vpextrq_3 = "mri/qo:660F3Au16RmU",
vphaddw_3 = "rrmoy:660F38V01rM",
vphaddd_3 = "rrmoy:660F38V02rM",
vphaddsw_3 = "rrmoy:660F38V03rM",
vphminposuw_2 = "rmo:660F38u41rM",
vphsubw_3 = "rrmoy:660F38V05rM",
vphsubd_3 = "rrmoy:660F38V06rM",
vphsubsw_3 = "rrmoy:660F38V07rM",
vpinsrb_4 = "rrri/ood:660F3AV20rMU|rrxi/oob:",
vpinsrw_4 = "rrri/ood:660FVC4rMU|rrxi/oow:",
vpinsrd_4 = "rrmi/ood:660F3AV22rMU",
vpinsrq_4 = "rrmi/ooq:660F3AVX22rMU",
vpmaddubsw_3 = "rrmoy:660F38V04rM",
vpmaxsb_3 = "rrmoy:660F38V3CrM",
vpmaxsd_3 = "rrmoy:660F38V3DrM",
vpmaxuw_3 = "rrmoy:660F38V3ErM",
vpmaxud_3 = "rrmoy:660F38V3FrM",
vpminsb_3 = "rrmoy:660F38V38rM",
vpminsd_3 = "rrmoy:660F38V39rM",
vpminuw_3 = "rrmoy:660F38V3ArM",
vpminud_3 = "rrmoy:660F38V3BrM",
vpmovmskb_2 = "rr/do:660FuD7rM|rr/dy:660FuLD7rM",
vpmovsxbw_2 = "rroy:660F38u20rM|rx/oq:|rx/yo:",
vpmovsxbd_2 = "rroy:660F38u21rM|rx/od:|rx/yq:",
vpmovsxbq_2 = "rroy:660F38u22rM|rx/ow:|rx/yd:",
vpmovsxwd_2 = "rroy:660F38u23rM|rx/oq:|rx/yo:",
vpmovsxwq_2 = "rroy:660F38u24rM|rx/od:|rx/yq:",
vpmovsxdq_2 = "rroy:660F38u25rM|rx/oq:|rx/yo:",
vpmovzxbw_2 = "rroy:660F38u30rM|rx/oq:|rx/yo:",
vpmovzxbd_2 = "rroy:660F38u31rM|rx/od:|rx/yq:",
vpmovzxbq_2 = "rroy:660F38u32rM|rx/ow:|rx/yd:",
vpmovzxwd_2 = "rroy:660F38u33rM|rx/oq:|rx/yo:",
vpmovzxwq_2 = "rroy:660F38u34rM|rx/od:|rx/yq:",
vpmovzxdq_2 = "rroy:660F38u35rM|rx/oq:|rx/yo:",
vpmuldq_3 = "rrmoy:660F38V28rM",
vpmulhrsw_3 = "rrmoy:660F38V0BrM",
vpmulld_3 = "rrmoy:660F38V40rM",
vpshufb_3 = "rrmoy:660F38V00rM",
vpshufd_3 = "rmioy:660Fu70rMU",
vpshufhw_3 = "rmioy:F30Fu70rMU",
vpshuflw_3 = "rmioy:F20Fu70rMU",
vpsignb_3 = "rrmoy:660F38V08rM",
vpsignw_3 = "rrmoy:660F38V09rM",
vpsignd_3 = "rrmoy:660F38V0ArM",
vpslldq_3 = "rrioy:660Fv737mU",
vpsllw_3 = "rrmoy:660FVF1rM|rrioy:660Fv716mU",
vpslld_3 = "rrmoy:660FVF2rM|rrioy:660Fv726mU",
vpsllq_3 = "rrmoy:660FVF3rM|rrioy:660Fv736mU",
vpsraw_3 = "rrmoy:660FVE1rM|rrioy:660Fv714mU",
vpsrad_3 = "rrmoy:660FVE2rM|rrioy:660Fv724mU",
vpsrldq_3 = "rrioy:660Fv733mU",
vpsrlw_3 = "rrmoy:660FVD1rM|rrioy:660Fv712mU",
vpsrld_3 = "rrmoy:660FVD2rM|rrioy:660Fv722mU",
vpsrlq_3 = "rrmoy:660FVD3rM|rrioy:660Fv732mU",
vptest_2 = "rmoy:660F38u17rM",
-- AVX2 integer ops
vbroadcasti128_2 = "rx/yo:660F38u5ArM",
vinserti128_4 = "rrmi/yyo:660F3AV38rMU",
vextracti128_3 = "mri/oy:660F3AuL39RmU",
vpblendd_4 = "rrmioy:660F3AV02rMU",
vpbroadcastb_2 = "rro:660F38u78rM|rx/ob:|rr/yo:|rx/yb:",
vpbroadcastw_2 = "rro:660F38u79rM|rx/ow:|rr/yo:|rx/yw:",
vpbroadcastd_2 = "rro:660F38u58rM|rx/od:|rr/yo:|rx/yd:",
vpbroadcastq_2 = "rro:660F38u59rM|rx/oq:|rr/yo:|rx/yq:",
vpermd_3 = "rrmy:660F38V36rM",
vpermq_3 = "rmiy:660F3AuX00rMU",
-- *vpgather* (!vsib)
vperm2i128_4 = "rrmiy:660F3AV46rMU",
vpmaskmovd_3 = "rrxoy:660F38V8CrM|xrroy:660F38V8ERm",
vpmaskmovq_3 = "rrxoy:660F38VX8CrM|xrroy:660F38VX8ERm",
vpsllvd_3 = "rrmoy:660F38V47rM",
vpsllvq_3 = "rrmoy:660F38VX47rM",
vpsravd_3 = "rrmoy:660F38V46rM",
vpsrlvd_3 = "rrmoy:660F38V45rM",
vpsrlvq_3 = "rrmoy:660F38VX45rM",
}
------------------------------------------------------------------------------
@@ -1454,28 +1671,58 @@ for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
end
-- SSE FP arithmetic ops.
-- SSE / AVX FP arithmetic ops.
for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
sub = 12, min = 13, div = 14, max = 15 } do
map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
if n ~= 1 then
map_op["v"..name.."ps_3"] = format("rrmoy:0FV5%XrM", n)
map_op["v"..name.."ss_3"] = format("rrro:F30FV5%XrM|rrx/ood:", n)
map_op["v"..name.."pd_3"] = format("rrmoy:660FV5%XrM", n)
map_op["v"..name.."sd_3"] = format("rrro:F20FV5%XrM|rrx/ooq:", n)
end
end
-- SSE2 / AVX / AVX2 integer arithmetic ops (66 0F leaf).
for name,n in pairs{
paddb = 0xFC, paddw = 0xFD, paddd = 0xFE, paddq = 0xD4,
paddsb = 0xEC, paddsw = 0xED, packssdw = 0x6B,
packsswb = 0x63, packuswb = 0x67, paddusb = 0xDC,
paddusw = 0xDD, pand = 0xDB, pandn = 0xDF, pavgb = 0xE0,
pavgw = 0xE3, pcmpeqb = 0x74, pcmpeqd = 0x76,
pcmpeqw = 0x75, pcmpgtb = 0x64, pcmpgtd = 0x66,
pcmpgtw = 0x65, pmaddwd = 0xF5, pmaxsw = 0xEE,
pmaxub = 0xDE, pminsw = 0xEA, pminub = 0xDA,
pmulhuw = 0xE4, pmulhw = 0xE5, pmullw = 0xD5,
pmuludq = 0xF4, por = 0xEB, psadbw = 0xF6, psubb = 0xF8,
psubw = 0xF9, psubd = 0xFA, psubq = 0xFB, psubsb = 0xE8,
psubsw = 0xE9, psubusb = 0xD8, psubusw = 0xD9,
punpckhbw = 0x68, punpckhwd = 0x69, punpckhdq = 0x6A,
punpckhqdq = 0x6D, punpcklbw = 0x60, punpcklwd = 0x61,
punpckldq = 0x62, punpcklqdq = 0x6C, pxor = 0xEF
} do
map_op[name.."_2"] = format("rmo:660F%02XrM", n)
map_op["v"..name.."_3"] = format("rrmoy:660FV%02XrM", n)
end
------------------------------------------------------------------------------
local map_vexarg = { u = false, v = 1, V = 2 }
-- Process pattern string.
local function dopattern(pat, args, sz, op, needrex)
local digit, addin
local digit, addin, vex
local opcode = 0
local szov = sz
local narg = 1
local rex = 0
-- Limit number of section buffer positions used by a single dasm_put().
-- A single opcode needs a maximum of 5 positions.
if secpos+5 > maxsecpos then wflush() end
-- A single opcode needs a maximum of 6 positions.
if secpos+6 > maxsecpos then wflush() end
-- Process each character.
for c in gmatch(pat.."|", ".") do
@@ -1489,6 +1736,8 @@ local function dopattern(pat, args, sz, op, needrex)
szov = nil
elseif c == "X" then -- Force REX.W.
rex = 8
elseif c == "L" then -- Force VEX.L.
vex.l = true
elseif c == "r" then -- Merge 1st operand regno. into opcode.
addin = args[1]; opcode = opcode + (addin.reg % 8)
if narg < 2 then narg = 2 end
@@ -1512,21 +1761,41 @@ local function dopattern(pat, args, sz, op, needrex)
if t.xreg and t.xreg > 7 then rex = rex + 2 end
if s > 7 then rex = rex + 4 end
if needrex then rex = rex + 16 end
wputop(szov, opcode, rex); opcode = nil
wputop(szov, opcode, rex, vex); opcode = nil
local imark = sub(pat, -1) -- Force a mark (ugly).
-- Put ModRM/SIB with regno/last digit as spare.
wputmrmsib(t, imark, s, addin and addin.vreg)
addin = nil
elseif map_vexarg[c] ~= nil then -- Encode using VEX prefix
local b = band(opcode, 255); opcode = shr(opcode, 8)
local m = 1
if b == 0x38 then m = 2
elseif b == 0x3a then m = 3 end
if m ~= 1 then b = band(opcode, 255); opcode = shr(opcode, 8) end
if b ~= 0x0f then
werror("expected `0F', `0F38', or `0F3A' to precede `"..c..
"' in pattern `"..pat.."' for `"..op.."'")
end
local v = map_vexarg[c]
if v then v = remove(args, v) end
b = band(opcode, 255)
local p = 0
if b == 0x66 then p = 1
elseif b == 0xf3 then p = 2
elseif b == 0xf2 then p = 3 end
if p ~= 0 then opcode = shr(opcode, 8) end
if opcode ~= 0 then wputop(nil, opcode, 0); opcode = 0 end
vex = { m = m, p = p, v = v }
else
if opcode then -- Flush opcode.
if szov == "q" and rex == 0 then rex = rex + 8 end
if needrex then rex = rex + 16 end
if addin and addin.reg == -1 then
wputop(szov, opcode - 7, rex)
wputop(szov, opcode - 7, rex, vex)
waction("VREG", addin.vreg); wputxb(0)
else
if addin and addin.reg > 7 then rex = rex + 1 end
wputop(szov, opcode, rex)
wputop(szov, opcode, rex, vex)
end
opcode = nil
end
@@ -1563,6 +1832,14 @@ local function dopattern(pat, args, sz, op, needrex)
else
wputlabel("REL_", imm, 2)
end
elseif c == "s" then
local reg = a.reg
if reg < 0 then
wputb(0)
waction("VREG", a.vreg); wputxb(5)
else
wputb(shl(reg, 4))
end
else
werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
end
@@ -1639,11 +1916,14 @@ map_op[".template__"] = function(params, template, nparams)
if pat == "" then pat = lastpat else lastpat = pat end
if matchtm(tm, args) then
local prefix = sub(szm, 1, 1)
if prefix == "/" then -- Match both operand sizes.
if args[1].opsize == sub(szm, 2, 2) and
args[2].opsize == sub(szm, 3, 3) then
dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
return
if prefix == "/" then -- Exactly match leading operand sizes.
for i = #szm,1,-1 do
if i == 1 then
dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
return
elseif args[i-1].opsize ~= sub(szm, i, i) then
break
end
end
else -- Match common operand size.
local szp = sz
@@ -1678,7 +1958,7 @@ if x64 then
function map_op.mov64_2(params)
if not params then return { "reg, imm", "reg, [disp]", "[disp], reg" } end
if secpos+2 > maxsecpos then wflush() end
local opcode, op64, sz, rex
local opcode, op64, sz, rex, vreg
local op64 = match(params[1], "^%[%s*(.-)%s*%]$")
if op64 then
local a = parseoperand(params[2])
@@ -1699,11 +1979,17 @@ if x64 then
werror("bad operand mode")
end
op64 = params[2]
opcode = 0xb8 + band(a.reg, 7) -- !x64: no VREG support.
if a.reg == -1 then
vreg = a.vreg
opcode = 0xb8
else
opcode = 0xb8 + band(a.reg, 7)
end
rex = a.reg > 7 and 9 or 8
end
end
wputop(sz, opcode, rex)
if vreg then waction("VREG", vreg); wputxb(0) end
waction("IMM_D", format("(unsigned int)(%s)", op64))
waction("IMM_D", format("(unsigned int)((%s)>>32)", op64))
end
@@ -2,7 +2,7 @@
-- DynASM. A dynamic assembler for code generation engines.
-- Originally designed and implemented for LuaJIT.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- See below for full copyright notice.
------------------------------------------------------------------------------
@@ -10,14 +10,14 @@
local _info = {
name = "DynASM",
description = "A dynamic assembler for code generation engines",
version = "1.3.0",
vernum = 10300,
release = "2011-05-05",
version = "1.4.0",
vernum = 10400,
release = "2015-10-18",
author = "Mike Pall",
url = "http://luajit.org/dynasm.html",
license = "MIT",
copyright = [[
Copyright (C) 2005-2013 Mike Pall. All rights reserved.
Copyright (C) 2005-2015 Mike Pall. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -85,7 +85,7 @@ end
-- Resync CPP line numbers.
local function wsync()
if g_synclineno ~= g_lineno and g_opt.cpp then
wline("# "..g_lineno..' "'..g_fname..'"')
wline("#line "..g_lineno..' "'..g_fname..'"')
g_synclineno = g_lineno
end
end
@@ -695,6 +695,9 @@ map_op[".arch_1"] = function(params)
if not params then return "name" end
local err = loadarch(params[1])
if err then wfatal(err) end
wline(format("#if DASM_VERSION != %d", _info.vernum))
wline('#error "Version mismatch between DynASM and included encoding engine"')
wline("#endif")
end
-- Dummy .arch pseudo-opcode to improve the error report.
@@ -877,13 +880,9 @@ local function dasmhead(out)
** DO NOT EDIT! The original file is in "%s".
*/
#if DASM_VERSION != %d
#error "Version mismatch between DynASM and included encoding engine"
#endif
]], _info.url,
_info.version, g_arch._info.arch, g_arch._info.version,
g_fname, _info.vernum))
g_fname))
end
-- Read input file.
@@ -74,7 +74,7 @@ luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
Runs some nested loops and shows the resulting traces.
.SH COPYRIGHT
.PP
\fBLuaJIT\fR is Copyright \(co 2005-2013 Mike Pall.
\fBLuaJIT\fR is Copyright \(co 2005-2015 Mike Pall.
.br
\fBLuaJIT\fR is open source software, released under the MIT license.
.SH SEE ALSO
+25
View File
@@ -0,0 +1,25 @@
# Package information for LuaJIT to be used by pkg-config.
majver=2
minver=1
relver=0
version=${majver}.${minver}.${relver}-beta1
abiver=5.1
prefix=/usr/local
multilib=lib
exec_prefix=${prefix}
libdir=${exec_prefix}/${multilib}
libname=luajit-${abiver}
includedir=${prefix}/include/luajit-${majver}.${minver}
INSTALL_LMOD=${prefix}/share/lua/${abiver}
INSTALL_CMOD=${prefix}/${multilib}/lua/${abiver}
Name: LuaJIT
Description: Just-in-time compiler for Lua
URL: http://luajit.org
Version: ${version}
Requires:
Libs: -L${libdir} -l${libname}
Libs.private: -Wl,-E -lm -ldl
Cflags: -I${includedir}
+7
View File
@@ -0,0 +1,7 @@
luajit
lj_bcdef.h
lj_ffdef.h
lj_libdef.h
lj_recdef.h
lj_folddef.h
lj_vm.[sS]
+707
View File
@@ -0,0 +1,707 @@
##############################################################################
# LuaJIT Makefile. Requires GNU Make.
#
# Please read doc/install.html before changing any variables!
#
# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
# Also works with MinGW and Cygwin on Windows.
# Please check msvcbuild.bat for building with MSVC on Windows.
#
# Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
##############################################################################
MAJVER= 2
MINVER= 1
RELVER= 0
ABIVER= 5.1
NODOTABIVER= 51
##############################################################################
############################# COMPILER OPTIONS #############################
##############################################################################
# These options mainly affect the speed of the JIT compiler itself, not the
# speed of the JIT-compiled code. Turn any of the optional settings on by
# removing the '#' in front of them. Make sure you force a full recompile
# with "make clean", followed by "make" if you change any options.
#
DEFAULT_CC = gcc
#
# LuaJIT builds as a native 32 or 64 bit binary by default.
CC= $(DEFAULT_CC)
#
# Use this if you want to force a 32 bit build on a 64 bit multilib OS.
#CC= $(DEFAULT_CC) -m32
#
# Since the assembler part does NOT maintain a frame pointer, it's pointless
# to slow down the C part by not omitting it. Debugging, tracebacks and
# unwinding are not affected -- the assembler part has frame unwind
# information and GCC emits it where needed (x64) or with -g (see CCDEBUG).
CCOPT= -O2 -fomit-frame-pointer
# Use this if you want to generate a smaller binary (but it's slower):
#CCOPT= -Os -fomit-frame-pointer
# Note: it's no longer recommended to use -O3 with GCC 4.x.
# The I-Cache bloat usually outweighs the benefits from aggressive inlining.
#
# Target-specific compiler options:
#
# x86/x64 only: For GCC 4.2 or higher and if you don't intend to distribute
# the binaries to a different machine you could also use: -march=native
#
CCOPT_x86= -march=i686 -msse -msse2 -mfpmath=sse
CCOPT_x64=
CCOPT_arm=
CCOPT_arm64=
CCOPT_ppc=
CCOPT_mips=
#
CCDEBUG=
# Uncomment the next line to generate debug information:
#CCDEBUG= -g
#
CCWARN= -Wall
# Uncomment the next line to enable more warnings:
#CCWARN+= -Wextra -Wdeclaration-after-statement -Wredundant-decls -Wshadow -Wpointer-arith
#
##############################################################################
##############################################################################
################################ BUILD MODE ################################
##############################################################################
# The default build mode is mixed mode on POSIX. On Windows this is the same
# as dynamic mode.
#
# Mixed mode creates a static + dynamic library and a statically linked luajit.
BUILDMODE= mixed
#
# Static mode creates a static library and a statically linked luajit.
#BUILDMODE= static
#
# Dynamic mode creates a dynamic library and a dynamically linked luajit.
# Note: this executable will only run when the library is installed!
#BUILDMODE= dynamic
#
##############################################################################
##############################################################################
################################# FEATURES #################################
##############################################################################
# Enable/disable these features as needed, but make sure you force a full
# recompile with "make clean", followed by "make".
XCFLAGS=
#
# Permanently disable the FFI extension to reduce the size of the LuaJIT
# executable. But please consider that the FFI library is compiled-in,
# but NOT loaded by default. It only allocates any memory, if you actually
# make use of it.
#XCFLAGS+= -DLUAJIT_DISABLE_FFI
#
# Features from Lua 5.2 that are unlikely to break existing code are
# enabled by default. Some other features that *might* break some existing
# code (e.g. __pairs or os.execute() return values) can be enabled here.
# Note: this does not provide full compatibility with Lua 5.2 at this time.
#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
#
# Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter.
#XCFLAGS+= -DLUAJIT_DISABLE_JIT
#
# Some architectures (e.g. PPC) can use either single-number (1) or
# dual-number (2) mode. Uncomment one of these lines to override the
# default mode. Please see LJ_ARCH_NUMMODE in lj_arch.h for details.
#XCFLAGS+= -DLUAJIT_NUMMODE=1
#XCFLAGS+= -DLUAJIT_NUMMODE=2
#
##############################################################################
##############################################################################
############################ DEBUGGING SUPPORT #############################
##############################################################################
# Enable these options as needed, but make sure you force a full recompile
# with "make clean", followed by "make".
# Note that most of these are NOT suitable for benchmarking or release mode!
#
# Use the system provided memory allocator (realloc) instead of the
# bundled memory allocator. This is slower, but sometimes helpful for
# debugging. This option cannot be enabled on x64, since realloc usually
# doesn't return addresses in the right address range.
# OTOH this option is mandatory for Valgrind's memcheck tool on x64 and
# the only way to get useful results from it for all other architectures.
#XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
#
# This define is required to run LuaJIT under Valgrind. The Valgrind
# header files must be installed. You should enable debug information, too.
# Use --suppressions=lj.supp to avoid some false positives.
#XCFLAGS+= -DLUAJIT_USE_VALGRIND
#
# This is the client for the GDB JIT API. GDB 7.0 or higher is required
# to make use of it. See lj_gdbjit.c for details. Enabling this causes
# a non-negligible overhead, even when not running under GDB.
#XCFLAGS+= -DLUAJIT_USE_GDBJIT
#
# Turn on assertions for the Lua/C API to debug problems with lua_* calls.
# This is rather slow -- use only while developing C libraries/embeddings.
#XCFLAGS+= -DLUA_USE_APICHECK
#
# Turn on assertions for the whole LuaJIT VM. This significantly slows down
# everything. Use only if you suspect a problem with LuaJIT itself.
#XCFLAGS+= -DLUA_USE_ASSERT
#
##############################################################################
# You probably don't need to change anything below this line!
##############################################################################
##############################################################################
# Host system detection.
##############################################################################
ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM))
HOST_SYS= Windows
HOST_RM= del
else
HOST_SYS:= $(shell uname -s)
ifneq (,$(findstring MINGW,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= mingw
endif
ifneq (,$(findstring CYGWIN,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= cygwin
endif
# Use Clang for OSX host.
ifeq (Darwin,$(HOST_SYS))
DEFAULT_CC= clang
endif
endif
##############################################################################
# Flags and options for host and target.
##############################################################################
# You can override the following variables at the make command line:
# CC HOST_CC STATIC_CC DYNAMIC_CC
# CFLAGS HOST_CFLAGS TARGET_CFLAGS
# LDFLAGS HOST_LDFLAGS TARGET_LDFLAGS TARGET_SHLDFLAGS
# LIBS HOST_LIBS TARGET_LIBS
# CROSS HOST_SYS TARGET_SYS TARGET_FLAGS
#
# Cross-compilation examples:
# make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
# make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
ASOPTIONS= $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS)
CCOPTIONS= $(CCDEBUG) $(ASOPTIONS)
LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
HOST_CC= $(CC)
HOST_RM= rm -f
# If left blank, minilua is built and used. You can supply an installed
# copy of (plain) Lua 5.1 or 5.2, plus Lua BitOp. E.g. with: HOST_LUA=lua
HOST_LUA=
HOST_XCFLAGS= -I.
HOST_XLDFLAGS=
HOST_XLIBS=
HOST_ACFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) $(HOST_CFLAGS)
HOST_ALDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) $(HOST_LDFLAGS)
HOST_ALIBS= $(HOST_XLIBS) $(LIBS) $(HOST_LIBS)
STATIC_CC = $(CROSS)$(CC)
DYNAMIC_CC = $(CROSS)$(CC) -fPIC
TARGET_CC= $(STATIC_CC)
TARGET_STCC= $(STATIC_CC)
TARGET_DYNCC= $(DYNAMIC_CC)
TARGET_LD= $(CROSS)$(CC)
TARGET_AR= $(CROSS)ar rcus
TARGET_STRIP= $(CROSS)strip
TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)
TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
TARGET_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).dylib
TARGET_DYLIBPATH= $(TARGET_LIBPATH)/$(TARGET_DYLIBNAME)
TARGET_DLLNAME= lua$(NODOTABIVER).dll
TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
TARGET_DYNXLDOPTS=
TARGET_LFSFLAGS= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
TARGET_XCFLAGS= $(TARGET_LFSFLAGS) -U_FORTIFY_SOURCE
TARGET_XLDFLAGS=
TARGET_XLIBS= -lm
TARGET_TCFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
TARGET_ACFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
TARGET_ASFLAGS= $(ASOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
TARGET_ALDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_FLAGS) $(TARGET_LDFLAGS)
TARGET_ASHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS) $(TARGET_FLAGS) $(TARGET_SHLDFLAGS)
TARGET_ALIBS= $(TARGET_XLIBS) $(LIBS) $(TARGET_LIBS)
TARGET_TESTARCH=$(shell $(TARGET_CC) $(TARGET_TCFLAGS) -E lj_arch.h -dM)
ifneq (,$(findstring LJ_TARGET_X64 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= x64
else
ifneq (,$(findstring LJ_TARGET_X86 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= x86
else
ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH)))
TARGET_LJARCH= arm
else
ifneq (,$(findstring LJ_TARGET_ARM64 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= arm64
else
ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
ifneq (,$(findstring LJ_LE 1,$(TARGET_TESTARCH)))
TARGET_ARCH= -DLJ_ARCH_ENDIAN=LUAJIT_LE
else
TARGET_ARCH= -DLJ_ARCH_ENDIAN=LUAJIT_BE
endif
TARGET_LJARCH= ppc
else
ifneq (,$(findstring LJ_TARGET_MIPS ,$(TARGET_TESTARCH)))
ifneq (,$(findstring MIPSEL ,$(TARGET_TESTARCH)))
TARGET_ARCH= -D__MIPSEL__=1
endif
TARGET_LJARCH= mips
else
$(error Unsupported target architecture)
endif
endif
endif
endif
endif
endif
ifneq (,$(findstring LJ_TARGET_PS3 1,$(TARGET_TESTARCH)))
TARGET_SYS= PS3
TARGET_ARCH+= -D__CELLOS_LV2__
TARGET_XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
TARGET_XLIBS+= -lpthread
endif
TARGET_XCFLAGS+= $(CCOPT_$(TARGET_LJARCH))
TARGET_ARCH+= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET_LJARCH))
ifneq (,$(PREFIX))
ifneq (/usr/local,$(PREFIX))
TARGET_XCFLAGS+= -DLUA_ROOT=\"$(PREFIX)\"
ifneq (/usr,$(PREFIX))
TARGET_DYNXLDOPTS= -Wl,-rpath,$(TARGET_LIBPATH)
endif
endif
endif
ifneq (,$(MULTILIB))
TARGET_XCFLAGS+= -DLUA_MULTILIB=\"$(MULTILIB)\"
endif
ifneq (,$(LMULTILIB))
TARGET_XCFLAGS+= -DLUA_LMULTILIB=\"$(LMULTILIB)\"
endif
##############################################################################
# Target system detection.
##############################################################################
TARGET_SYS?= $(HOST_SYS)
ifeq (Windows,$(TARGET_SYS))
TARGET_STRIP+= --strip-unneeded
TARGET_XSHLDFLAGS= -shared
TARGET_DYNXLDOPTS=
else
ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-stack-protector 2>/dev/null || echo 1))
TARGET_XCFLAGS+= -fno-stack-protector
endif
ifeq (Darwin,$(TARGET_SYS))
ifeq (,$(MACOSX_DEPLOYMENT_TARGET))
export MACOSX_DEPLOYMENT_TARGET=10.4
endif
TARGET_STRIP+= -x
TARGET_AR+= 2>/dev/null
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
TARGET_DYNXLDOPTS=
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
ifeq (x64,$(TARGET_LJARCH))
TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000
TARGET_XSHLDFLAGS+= -image_base 7fff04c4a000
endif
else
ifeq (iOS,$(TARGET_SYS))
TARGET_STRIP+= -x
TARGET_AR+= 2>/dev/null
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
TARGET_DYNXLDOPTS=
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
ifeq (arm64,$(TARGET_LJARCH))
TARGET_XCFLAGS+= -fno-omit-frame-pointer
endif
else
ifneq (SunOS,$(TARGET_SYS))
ifneq (PS3,$(TARGET_SYS))
TARGET_XLDFLAGS+= -Wl,-E
endif
endif
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
ifeq (GNU/kFreeBSD,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
endif
endif
endif
ifneq ($(HOST_SYS),$(TARGET_SYS))
ifeq (Windows,$(TARGET_SYS))
HOST_XCFLAGS+= -malign-double -DLUAJIT_OS=LUAJIT_OS_WINDOWS
else
ifeq (Linux,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_LINUX
else
ifeq (Darwin,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
else
ifeq (iOS,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
else
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
endif
endif
endif
endif
endif
ifneq (,$(CCDEBUG))
TARGET_STRIP= @:
endif
##############################################################################
# Files and pathnames.
##############################################################################
MINILUA_O= host/minilua.o
MINILUA_LIBS= -lm
MINILUA_T= host/minilua
MINILUA_X= $(MINILUA_T)
ifeq (,$(HOST_LUA))
HOST_LUA= $(MINILUA_X)
DASM_DEP= $(MINILUA_T)
endif
DASM_DIR= ../dynasm
DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
DASM_XFLAGS=
DASM_AFLAGS=
DASM_ARCH= $(TARGET_LJARCH)
ifneq (,$(findstring LJ_ARCH_BITS 64,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D P64
endif
ifneq (,$(findstring LJ_HASJIT 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D JIT
endif
ifneq (,$(findstring LJ_HASFFI 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FFI
endif
ifneq (,$(findstring LJ_DUALNUM 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D DUALNUM
endif
ifneq (,$(findstring LJ_ARCH_HASFPU 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FPU
TARGET_ARCH+= -DLJ_ARCH_HASFPU=1
else
TARGET_ARCH+= -DLJ_ARCH_HASFPU=0
endif
ifeq (,$(findstring LJ_ABI_SOFTFP 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D HFABI
TARGET_ARCH+= -DLJ_ABI_SOFTFP=0
else
TARGET_ARCH+= -DLJ_ABI_SOFTFP=1
endif
ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D NO_UNWIND
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
endif
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
ifeq (Windows,$(TARGET_SYS))
DASM_AFLAGS+= -D WIN
endif
ifeq (x64,$(TARGET_LJARCH))
ifeq (,$(findstring LJ_FR2 1,$(TARGET_TESTARCH)))
DASM_ARCH= x86
endif
else
ifeq (arm,$(TARGET_LJARCH))
ifeq (iOS,$(TARGET_SYS))
DASM_AFLAGS+= -D IOS
endif
else
ifeq (ppc,$(TARGET_LJARCH))
ifneq (,$(findstring LJ_ARCH_SQRT 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D SQRT
endif
ifneq (,$(findstring LJ_ARCH_ROUND 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D ROUND
endif
ifneq (,$(findstring LJ_ARCH_PPC32ON64 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D GPR64
endif
ifeq (PS3,$(TARGET_SYS))
DASM_AFLAGS+= -D PPE -D TOC
endif
ifneq (,$(findstring LJ_ARCH_PPC64 ,$(TARGET_TESTARCH)))
DASM_ARCH= ppc64
endif
endif
endif
endif
DASM_FLAGS= $(DASM_XFLAGS) $(DASM_AFLAGS)
DASM_DASC= vm_$(DASM_ARCH).dasc
BUILDVM_O= host/buildvm.o host/buildvm_asm.o host/buildvm_peobj.o \
host/buildvm_lib.o host/buildvm_fold.o
BUILDVM_T= host/buildvm
BUILDVM_X= $(BUILDVM_T)
HOST_O= $(MINILUA_O) $(BUILDVM_O)
HOST_T= $(MINILUA_T) $(BUILDVM_T)
LJVM_S= lj_vm.S
LJVM_O= lj_vm.o
LJVM_BOUT= $(LJVM_S)
LJVM_MODE= elfasm
LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o
LJLIB_C= $(LJLIB_O:.o=.c)
LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \
lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_strscan.o \
lj_strfmt.o lj_api.o lj_profile.o \
lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \
lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \
lj_asm.o lj_trace.o lj_gdbjit.o \
lj_ctype.o lj_cdata.o lj_cconv.o lj_ccall.o lj_ccallback.o \
lj_carith.o lj_clib.o lj_cparse.o \
lj_lib.o lj_alloc.o lib_aux.o \
$(LJLIB_O) lib_init.o
LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
LIB_VMDEF= jit/vmdef.lua
LIB_VMDEFP= $(LIB_VMDEF)
LUAJIT_O= luajit.o
LUAJIT_A= libluajit.a
LUAJIT_SO= libluajit.so
LUAJIT_T= luajit
ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(HOST_T)
ALL_HDRGEN= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h \
host/buildvm_arch.h
ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP)
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
ALL_RM= $(ALL_T) $(ALL_GEN) *.o host/*.o $(WIN_RM)
##############################################################################
# Build mode handling.
##############################################################################
# Mixed mode defaults.
TARGET_O= $(LUAJIT_A)
TARGET_T= $(LUAJIT_T) $(LUAJIT_SO)
TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO)
ifeq (Windows,$(TARGET_SYS))
TARGET_DYNCC= $(STATIC_CC)
LJVM_MODE= peobj
LJVM_BOUT= $(LJVM_O)
LUAJIT_T= luajit.exe
ifeq (cygwin,$(HOST_MSYS))
LUAJIT_SO= cyg$(TARGET_DLLNAME)
else
LUAJIT_SO= $(TARGET_DLLNAME)
endif
# Mixed mode is not supported on Windows. And static mode doesn't work well.
# C modules cannot be loaded, because they bind to lua51.dll.
ifneq (static,$(BUILDMODE))
BUILDMODE= dynamic
TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
endif
endif
ifeq (Darwin,$(TARGET_SYS))
LJVM_MODE= machasm
endif
ifeq (iOS,$(TARGET_SYS))
LJVM_MODE= machasm
endif
ifeq (SunOS,$(TARGET_SYS))
BUILDMODE= static
endif
ifeq (PS3,$(TARGET_SYS))
BUILDMODE= static
endif
ifeq (Windows,$(HOST_SYS))
MINILUA_T= host/minilua.exe
BUILDVM_T= host/buildvm.exe
ifeq (,$(HOST_MSYS))
MINILUA_X= host\minilua
BUILDVM_X= host\buildvm
ALL_RM:= $(subst /,\,$(ALL_RM))
endif
endif
ifeq (static,$(BUILDMODE))
TARGET_DYNCC= @:
TARGET_T= $(LUAJIT_T)
TARGET_DEP= $(LIB_VMDEF)
else
ifeq (dynamic,$(BUILDMODE))
ifneq (Windows,$(TARGET_SYS))
TARGET_CC= $(DYNAMIC_CC)
endif
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
TARGET_O= $(LUAJIT_SO)
TARGET_XLDFLAGS+= $(TARGET_DYNXLDOPTS)
else
ifeq (Darwin,$(TARGET_SYS))
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
endif
ifeq (iOS,$(TARGET_SYS))
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
endif
endif
endif
Q= @
E= @echo
#Q=
#E= @:
##############################################################################
# Make targets.
##############################################################################
default all: $(TARGET_T)
amalg:
@grep "^[+|]" ljamalg.c
$(MAKE) all "LJCORE_O=ljamalg.o"
clean:
$(HOST_RM) $(ALL_RM)
libbc:
./$(LUAJIT_T) host/genlibbc.lua -o host/buildvm_libbc.h $(LJLIB_C)
$(MAKE) all
depend:
@for file in $(ALL_HDRGEN); do \
test -f $$file || touch $$file; \
done
@$(HOST_CC) $(HOST_ACFLAGS) -MM *.c host/*.c | \
sed -e "s| [^ ]*/dasm_\S*\.h||g" \
-e "s|^\([^l ]\)|host/\1|" \
-e "s| lj_target_\S*\.h| lj_target_*.h|g" \
-e "s| lj_emit_\S*\.h| lj_emit_*.h|g" \
-e "s| lj_asm_\S*\.h| lj_asm_*.h|g" >Makefile.dep
@for file in $(ALL_HDRGEN); do \
test -s $$file || $(HOST_RM) $$file; \
done
.PHONY: default all amalg clean libbc depend
##############################################################################
# Rules for generated files.
##############################################################################
$(MINILUA_T): $(MINILUA_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(MINILUA_O) $(MINILUA_LIBS) $(HOST_ALIBS)
host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP)
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC)
host/buildvm.o: $(DASM_DIR)/dasm_*.h
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(BUILDVM_O) $(HOST_ALIBS)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
lj_bcdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m bcdef -o $@ $(LJLIB_C)
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
##############################################################################
# Object file rules.
##############################################################################
%.o: %.c
$(E) "CC $@"
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
%.o: %.S
$(E) "ASM $@"
$(Q)$(TARGET_DYNCC) $(TARGET_ASFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_ASFLAGS) -c -o $@ $<
$(LUAJIT_O):
$(E) "CC $@"
$(Q)$(TARGET_STCC) $(TARGET_ACFLAGS) -c -o $@ $<
$(HOST_O): %.o: %.c
$(E) "HOSTCC $@"
$(Q)$(HOST_CC) $(HOST_ACFLAGS) -c -o $@ $<
include Makefile.dep
##############################################################################
# Target file rules.
##############################################################################
$(LUAJIT_A): $(LJVMCORE_O)
$(E) "AR $@"
$(Q)$(TARGET_AR) $@ $(LJVMCORE_O)
# The dependency on _O, but linking with _DYNO is intentional.
$(LUAJIT_SO): $(LJVMCORE_O)
$(E) "DYNLINK $@"
$(Q)$(TARGET_LD) $(TARGET_ASHLDFLAGS) -o $@ $(LJVMCORE_DYNO) $(TARGET_ALIBS)
$(Q)$(TARGET_STRIP) $@
$(LUAJIT_T): $(TARGET_O) $(LUAJIT_O) $(TARGET_DEP)
$(E) "LINK $@"
$(Q)$(TARGET_LD) $(TARGET_ALDFLAGS) -o $@ $(LUAJIT_O) $(TARGET_O) $(TARGET_ALIBS)
$(Q)$(TARGET_STRIP) $@
$(E) "OK Successfully built LuaJIT"
##############################################################################
+244
View File
@@ -0,0 +1,244 @@
lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
lj_strfmt.h lj_lib.h lj_libdef.h
lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \
lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \
lj_ffdef.h lj_lib.h lj_libdef.h
lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
lj_libdef.h
lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h \
lj_ctype.h lj_cparse.h lj_cdata.h lj_cconv.h lj_carith.h lj_ccall.h \
lj_ccallback.h lj_clib.h lj_strfmt.h lj_ff.h lj_ffdef.h lj_lib.h \
lj_libdef.h
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_state.h \
lj_strfmt.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
lj_state.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
lj_target.h lj_target_*.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
lj_libdef.h
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
lj_tab.h lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h \
lj_char.h lj_strfmt.h lj_lib.h lj_libdef.h
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h lj_strfmt.h
lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \
lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
lj_asm_*.h
lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
lj_bcdef.h
lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_bc.h \
lj_ctype.h lj_cdata.h lualib.h lj_lex.h lj_bcdump.h lj_state.h \
lj_strfmt.h
lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \
lj_ir.h lj_strfmt.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_strfmt.h
lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ir.h lj_ctype.h \
lj_cconv.h lj_cdata.h lj_carith.h lj_strscan.h
lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h \
lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
lj_traceerr.h
lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
lj_bc.h lj_ctype.h lj_cconv.h lj_ccall.h lj_ccallback.h lj_target.h \
lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \
lj_traceerr.h lj_vm.h
lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
lj_ccallback.h
lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h
lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_clib.h lj_strfmt.h
lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ctype.h lj_cparse.h \
lj_frame.h lj_bc.h lj_vm.h lj_char.h lj_strscan.h lj_strfmt.h
lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_gc.h \
lj_cdata.h lj_cparse.h lj_cconv.h lj_carith.h lj_clib.h lj_ccall.h \
lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \
lj_crecord.h lj_strfmt.h
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_strfmt.h lj_ctype.h \
lj_ccallback.h
lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
lj_state.h lj_frame.h lj_bc.h lj_strfmt.h lj_jit.h lj_ir.h
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_func.h lj_tab.h \
lj_meta.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \
lj_strfmt.h lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_profile.h lj_vm.h luajit.h
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
lj_traceerr.h lj_vm.h lj_strfmt.h
lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
lj_vm.h lj_strscan.h lj_strfmt.h lj_recdef.h
lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
lj_traceerr.h lj_vm.h
lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \
lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \
lj_str.h lj_strfmt.h lj_jit.h lj_ir.h lj_dispatch.h
lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_buf.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h \
lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \
lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h \
lj_strfmt.h
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lex.h \
lj_bcdump.h lj_lib.h
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \
lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_vm.h
lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h
lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_buf.h lj_gc.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h \
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h \
lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_folddef.h
lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h lj_jit.h \
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
lj_vm.h
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_ircall.h
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
lj_traceerr.h lj_vm.h lj_strscan.h
lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \
lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \
lj_vm.h lj_vmevent.h
lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \
lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \
lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h
lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
lj_target_*.h lj_ctype.h lj_cdata.h
lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h \
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h \
lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h luajit.h
lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_char.h
lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_buf.h lj_gc.h lj_str.h lj_state.h lj_char.h lj_strfmt.h
lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_char.h lj_strscan.h
lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_tab.h
lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_udata.h
lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
lj_vm.h lj_vmevent.h
lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_vm.h
ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h \
lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h \
lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h \
lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h lj_char.c \
lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c lj_tab.c \
lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h lj_debug.c \
lj_state.c lj_lex.h lj_alloc.h luajit.h lj_dispatch.c lj_ccallback.h \
lj_profile.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c \
lj_strfmt.c lj_api.c lj_profile.c lj_lex.c lualib.h lj_parse.h \
lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c \
lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c \
lj_target.h lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c \
lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h \
lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \
lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c \
lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \
lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \
lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \
lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
lib_init.c
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
lj_ircall.h lj_ir.h lj_jit.h lj_frame.h lj_bc.h lj_dispatch.h lj_ctype.h \
lj_gc.h lj_ccall.h lj_ctype.h luajit.h \
host/buildvm_arch.h lj_traceerr.h
host/buildvm_asm.o: host/buildvm_asm.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_bc.h lj_def.h lj_arch.h
host/buildvm_fold.o: host/buildvm_fold.c host/buildvm.h lj_def.h lua.h \
luaconf.h lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_ir.h lj_obj.h
host/buildvm_lib.o: host/buildvm_lib.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_bc.h lj_lib.h lj_obj.h \
host/buildvm_libbc.h
host/buildvm_peobj.o: host/buildvm_peobj.c host/buildvm.h lj_def.h lua.h \
luaconf.h lj_arch.h lj_bc.h lj_def.h lj_arch.h
host/minilua.o: host/minilua.c
+3
View File
@@ -0,0 +1,3 @@
minilua
buildvm
buildvm_arch.h
@@ -1,6 +1,6 @@
/*
** LuaJIT VM builder.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
**
** This is a tool to build the hand-tuned assembler code required for
** LuaJIT's bytecode interpreter. It supports a variety of output formats
@@ -59,10 +59,10 @@ static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type);
#include "../dynasm/dasm_x86.h"
#elif LJ_TARGET_ARM
#include "../dynasm/dasm_arm.h"
#elif LJ_TARGET_ARM64
#include "../dynasm/dasm_arm64.h"
#elif LJ_TARGET_PPC
#include "../dynasm/dasm_ppc.h"
#elif LJ_TARGET_PPCSPE
#include "../dynasm/dasm_ppc.h"
#elif LJ_TARGET_MIPS
#include "../dynasm/dasm_mips.h"
#else
@@ -108,10 +108,16 @@ static const char *sym_decorate(BuildCtx *ctx,
sprintf(name, "%s%s%s", symprefix, prefix, suffix);
p = strchr(name, '@');
if (p) {
#if LJ_TARGET_X86ORX64
if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj))
name[0] = '@';
else
*p = '\0';
#elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE
/* Keep @plt etc. */
#else
*p = '\0';
#endif
}
p = (char *)malloc(strlen(name)+1); /* MSVC doesn't like strdup. */
strcpy(p, name);
@@ -173,6 +179,7 @@ static int build_code(BuildCtx *ctx)
ctx->nreloc = 0;
ctx->globnames = globnames;
ctx->extnames = extnames;
ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
ctx->nrelocsym = 0;
for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;
@@ -314,20 +321,20 @@ static void emit_vmdef(BuildCtx *ctx)
char buf[80];
int i;
fprintf(ctx->fp, "-- This is a generated file. DO NOT EDIT!\n\n");
fprintf(ctx->fp, "module(...)\n\n");
fprintf(ctx->fp, "return {\n\n");
fprintf(ctx->fp, "bcnames = \"");
for (i = 0; bc_names[i]; i++) fprintf(ctx->fp, "%-6s", bc_names[i]);
fprintf(ctx->fp, "\"\n\n");
fprintf(ctx->fp, "\",\n\n");
fprintf(ctx->fp, "irnames = \"");
for (i = 0; ir_names[i]; i++) fprintf(ctx->fp, "%-6s", ir_names[i]);
fprintf(ctx->fp, "\"\n\n");
fprintf(ctx->fp, "\",\n\n");
fprintf(ctx->fp, "irfpm = { [0]=");
for (i = 0; irfpm_names[i]; i++)
fprintf(ctx->fp, "\"%s\", ", lower(buf, irfpm_names[i]));
fprintf(ctx->fp, "}\n\n");
fprintf(ctx->fp, "},\n\n");
fprintf(ctx->fp, "irfield = { [0]=");
for (i = 0; irfield_names[i]; i++) {
@@ -337,17 +344,17 @@ static void emit_vmdef(BuildCtx *ctx)
if (p) *p = '.';
fprintf(ctx->fp, "\"%s\", ", buf);
}
fprintf(ctx->fp, "}\n\n");
fprintf(ctx->fp, "},\n\n");
fprintf(ctx->fp, "ircall = {\n[0]=");
for (i = 0; ircall_names[i]; i++)
fprintf(ctx->fp, "\"%s\",\n", ircall_names[i]);
fprintf(ctx->fp, "}\n\n");
fprintf(ctx->fp, "},\n\n");
fprintf(ctx->fp, "traceerr = {\n[0]=");
for (i = 0; trace_errors[i]; i++)
fprintf(ctx->fp, "\"%s\",\n", trace_errors[i]);
fprintf(ctx->fp, "}\n\n");
fprintf(ctx->fp, "},\n\n");
}
/* -- Argument parsing ---------------------------------------------------- */
@@ -484,6 +491,7 @@ int main(int argc, char **argv)
case BUILD_vmdef:
emit_vmdef(ctx);
emit_lib(ctx);
fprintf(ctx->fp, "}\n\n");
break;
case BUILD_ffdef:
case BUILD_libdef:
@@ -1,6 +1,6 @@
/*
** LuaJIT VM builder.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
*/
#ifndef _BUILDVM_H
@@ -82,6 +82,7 @@ typedef struct BuildCtx {
const char *beginsym;
/* Strings generated by DynASM. */
const char *const *globnames;
const char *const *extnames;
const char *dasm_ident;
const char *dasm_arch;
/* Relocations. */
@@ -1,6 +1,6 @@
/*
** LuaJIT VM builder: Assembler source code emitter.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
*/
#include "buildvm.h"
@@ -51,8 +51,8 @@ static const char *const jccnames[] = {
"js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg"
};
/* Emit relocation for the incredibly stupid OSX assembler. */
static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n,
/* Emit x86/x64 text relocations. */
static void emit_asm_reloc_text(BuildCtx *ctx, uint8_t *cp, int n,
const char *sym)
{
const char *opname = NULL;
@@ -71,6 +71,20 @@ err:
exit(1);
}
emit_asm_bytes(ctx, cp, n);
if (strncmp(sym+(*sym == '_'), LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) {
/* Various fixups for external symbols outside of our binary. */
if (ctx->mode == BUILD_elfasm) {
if (LJ_32)
fprintf(ctx->fp, "#if __PIC__\n\t%s lj_wrap_%s\n#else\n", opname, sym);
fprintf(ctx->fp, "\t%s %s@PLT\n", opname, sym);
if (LJ_32)
fprintf(ctx->fp, "#endif\n");
return;
} else if (LJ_32 && ctx->mode == BUILD_machasm) {
fprintf(ctx->fp, "\t%s L%s$stub\n", opname, sym);
return;
}
}
fprintf(ctx->fp, "\t%s %s\n", opname, sym);
}
#else
@@ -100,14 +114,23 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
fprintf(ctx->fp, "\tblx %s\n", sym);
} else if ((ins & 0x0e000000u) == 0x0a000000u) {
fprintf(ctx->fp, "\t%s%.2s %s\n", (ins & 0x01000000u) ? "bl" : "b",
"eqnecsccmiplvsvchilsgeltgtle" + 2*(ins >> 28), sym);
&"eqnecsccmiplvsvchilsgeltgtle"[2*(ins >> 28)], sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
#elif LJ_TARGET_ARM64
if ((ins >> 26) == 0x25u) {
fprintf(ctx->fp, "\tbl %s\n", sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_PPC
#if LJ_TARGET_PS3
#define TOCPREFIX "."
#else
@@ -117,6 +140,14 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
(ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
} else if ((ins >> 26) == 18) {
#if LJ_ARCH_PPC64
const char *suffix = strchr(sym, '@');
if (suffix && suffix[1] == 'h') {
fprintf(ctx->fp, "\taddis 11, 2, %s\n", sym);
} else if (suffix && suffix[1] == 'l') {
fprintf(ctx->fp, "\tld 12, %s\n", sym);
} else
#endif
fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
} else {
fprintf(stderr,
@@ -214,6 +245,9 @@ void emit_asm(BuildCtx *ctx)
int i, rel;
fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
#if LJ_ARCH_PPC64
fprintf(ctx->fp, "\t.abiversion 2\n");
#endif
fprintf(ctx->fp, "\t.text\n");
emit_asm_align(ctx, 4);
@@ -254,8 +288,9 @@ void emit_asm(BuildCtx *ctx)
BuildReloc *r = &ctx->reloc[rel];
int n = r->ofs - ofs;
#if LJ_TARGET_X86ORX64
if (ctx->mode == BUILD_machasm && r->type != 0) {
emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
if (r->type != 0 &&
(ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) {
emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
} else {
emit_asm_bytes(ctx, ctx->code+ofs, n);
emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]);
@@ -286,13 +321,10 @@ void emit_asm(BuildCtx *ctx)
fprintf(ctx->fp, "\n");
switch (ctx->mode) {
case BUILD_elfasm:
#if !LJ_TARGET_PS3
#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
#endif
#if LJ_TARGET_PPCSPE
/* Soft-float ABI + SPE. */
fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n");
#elif LJ_TARGET_PPC && !LJ_TARGET_PS3
#if LJ_TARGET_PPC && !LJ_TARGET_PS3
/* Hard-float ABI. */
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
#endif
@@ -1,6 +1,6 @@
/*
** LuaJIT VM builder: IR folding hash table generator.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
*/
#include "buildvm.h"
@@ -1,11 +1,13 @@
/*
** LuaJIT VM builder: library definition compiler.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
*/
#include "buildvm.h"
#include "lj_obj.h"
#include "lj_bc.h"
#include "lj_lib.h"
#include "buildvm_libbc.h"
/* Context for library definitions. */
static uint8_t obuf[8192];
@@ -151,6 +153,62 @@ static void libdef_func(BuildCtx *ctx, char *p, int arg)
regfunc = REGFUNC_OK;
}
static uint8_t *libdef_uleb128(uint8_t *p, uint32_t *vv)
{
uint32_t v = *p++;
if (v >= 0x80) {
int sh = 0; v &= 0x7f;
do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
}
*vv = v;
return p;
}
static void libdef_fixupbc(uint8_t *p)
{
uint32_t i, sizebc;
p += 4;
p = libdef_uleb128(p, &sizebc);
p = libdef_uleb128(p, &sizebc);
p = libdef_uleb128(p, &sizebc);
for (i = 0; i < sizebc; i++, p += 4) {
uint8_t op = p[libbc_endian ? 3 : 0];
uint8_t ra = p[libbc_endian ? 2 : 1];
uint8_t rc = p[libbc_endian ? 1 : 2];
uint8_t rb = p[libbc_endian ? 0 : 3];
if (!LJ_DUALNUM && op == BC_ISTYPE && rc == ~LJ_TNUMX+1) {
op = BC_ISNUM; rc++;
}
p[LJ_ENDIAN_SELECT(0, 3)] = op;
p[LJ_ENDIAN_SELECT(1, 2)] = ra;
p[LJ_ENDIAN_SELECT(2, 1)] = rc;
p[LJ_ENDIAN_SELECT(3, 0)] = rb;
}
}
static void libdef_lua(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
int i;
for (i = 0; libbc_map[i].name != NULL; i++) {
if (!strcmp(libbc_map[i].name, p)) {
int ofs = libbc_map[i].ofs;
int len = libbc_map[i+1].ofs - ofs;
obuf[2]++; /* Bump hash table size. */
*optr++ = LIBINIT_LUA;
libdef_name(p, 0);
memcpy(optr, libbc_code + ofs, len);
libdef_fixupbc(optr);
optr += len;
return;
}
}
fprintf(stderr, "Error: missing libbc definition for %s\n", p);
exit(1);
}
}
static uint32_t find_rec(char *name)
{
char *p = (char *)obuf;
@@ -277,6 +335,7 @@ static const LibDefHandler libdef_handlers[] = {
{ "CF(", ")", libdef_func, LIBINIT_CF },
{ "ASM(", ")", libdef_func, LIBINIT_ASM },
{ "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
{ "LUA(", ")", libdef_lua, 0 },
{ "REC(", ")", libdef_rec, 0 },
{ "PUSH(", ")", libdef_push, 0 },
{ "SET(", ")", libdef_set, 0 },
@@ -373,7 +432,7 @@ void emit_lib(BuildCtx *ctx)
"#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
ffasmfunc);
} else if (ctx->mode == BUILD_vmdef) {
fprintf(ctx->fp, "}\n\n");
fprintf(ctx->fp, "},\n\n");
} else if (ctx->mode == BUILD_bcdef) {
int i;
fprintf(ctx->fp, "\n};\n\n");
+45
View File
@@ -0,0 +1,45 @@
/* This is a generated file. DO NOT EDIT! */
static const int libbc_endian = 0;
static const uint8_t libbc_code[] = {
#if LJ_FR2
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,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,0,1,2,0,0,0,3,
16,0,5,0,21,1,0,0,76,1,2,0,0,2,10,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,8,5,0,59,9,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,0,2,11,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,9,5,0,18,10,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,0,1,2,0,0,0,3,16,0,12,
0,21,1,0,0,76,1,2,0,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,16,1,14,
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,0
#else
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,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,0,1,2,0,0,0,3,
16,0,5,0,21,1,0,0,76,1,2,0,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,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,0,1,2,0,0,0,3,16,0,12,
0,21,1,0,0,76,1,2,0,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,16,1,14,
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,0
#endif
};
static const struct { const char *name; int ofs; } libbc_map[] = {
{"math_deg",0},
{"math_rad",25},
{"string_len",50},
{"table_foreachi",69},
{"table_foreach",136},
{"table_getn",207},
{"table_remove",226},
{NULL,355}
};
@@ -1,6 +1,6 @@
/*
** LuaJIT VM builder: PE object emitter.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
**
** Only used for building on Windows, since we cannot assume the presence
** of a suitable assembler. The host and target byte order must match.
+197
View File
@@ -0,0 +1,197 @@
----------------------------------------------------------------------------
-- Lua script to dump the bytecode of the library functions written in Lua.
-- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
----------------------------------------------------------------------------
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
local ffi = require("ffi")
local bit = require("bit")
local vmdef = require("jit.vmdef")
local bcnames = vmdef.bcnames
local format = string.format
local isbe = (string.byte(string.dump(function() end), 5) % 2 == 1)
local function usage(arg)
io.stderr:write("Usage: ", arg and arg[0] or "genlibbc",
" [-o buildvm_libbc.h] lib_*.c\n")
os.exit(1)
end
local function parse_arg(arg)
local outfile = "-"
if not (arg and arg[1]) then
usage(arg)
end
if arg[1] == "-o" then
outfile = arg[2]
if not outfile then usage(arg) end
table.remove(arg, 1)
table.remove(arg, 1)
end
return outfile
end
local function read_files(names)
local src = ""
for _,name in ipairs(names) do
local fp = assert(io.open(name))
src = src .. fp:read("*a")
fp:close()
end
return src
end
local function transform_lua(code)
local fixup = {}
local n = -30000
code = string.gsub(code, "CHECK_(%w*)%((.-)%)", function(tp, var)
n = n + 1
fixup[n] = { "CHECK", tp }
return format("%s=%d", var, n)
end)
code = string.gsub(code, "PAIRS%((.-)%)", function(var)
fixup.PAIRS = true
return format("nil, %s, 0", var)
end)
return "return "..code, fixup
end
local function read_uleb128(p)
local v = p[0]; p = p + 1
if v >= 128 then
local sh = 7; v = v - 128
repeat
local r = p[0]
v = v + bit.lshift(bit.band(r, 127), sh)
sh = sh + 7
p = p + 1
until r < 128
end
return p, v
end
-- ORDER LJ_T
local name2itype = {
str = 5, func = 9, tab = 12, int = 14, num = 15
}
local BC = {}
for i=0,#bcnames/6-1 do
BC[string.gsub(string.sub(bcnames, i*6+1, i*6+6), " ", "")] = i
end
local xop, xra = isbe and 3 or 0, isbe and 2 or 1
local xrc, xrb = isbe and 1 or 2, isbe and 0 or 3
local function fixup_dump(dump, fixup)
local buf = ffi.new("uint8_t[?]", #dump+1, dump)
local p = buf+5
local n, sizebc
p, n = read_uleb128(p)
local start = p
p = p + 4
p = read_uleb128(p)
p = read_uleb128(p)
p, sizebc = read_uleb128(p)
local rawtab = {}
for i=0,sizebc-1 do
local op = p[xop]
if op == BC.KSHORT then
local rd = p[xrc] + 256*p[xrb]
rd = bit.arshift(bit.lshift(rd, 16), 16)
local f = fixup[rd]
if f then
if f[1] == "CHECK" then
local tp = f[2]
if tp == "tab" then rawtab[p[xra]] = true end
p[xop] = tp == "num" and BC.ISNUM or BC.ISTYPE
p[xrb] = 0
p[xrc] = name2itype[tp]
else
error("unhandled fixup type: "..f[1])
end
end
elseif op == BC.TGETV then
if rawtab[p[xrb]] then
p[xop] = BC.TGETR
end
elseif op == BC.TSETV then
if rawtab[p[xrb]] then
p[xop] = BC.TSETR
end
elseif op == BC.ITERC then
if fixup.PAIRS then
p[xop] = BC.ITERN
end
end
p = p + 4
end
return ffi.string(start, n)
end
local function find_defs(src)
local defs = {}
for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
local env = {}
local tcode, fixup = transform_lua(code)
local func = assert(load(tcode, "", nil, env))()
defs[name] = fixup_dump(string.dump(func, true), fixup)
defs[#defs+1] = name
end
return defs
end
local function gen_header(defs)
local t = {}
local function w(x) t[#t+1] = x end
w("/* This is a generated file. DO NOT EDIT! */\n\n")
w("static const int libbc_endian = ") w(isbe and 1 or 0) w(";\n\n")
local s = ""
for _,name in ipairs(defs) do
s = s .. defs[name]
end
w("static const uint8_t libbc_code[] = {\n")
local n = 0
for i=1,#s do
local x = string.byte(s, i)
w(x); w(",")
n = n + (x < 10 and 2 or (x < 100 and 3 or 4))
if n >= 75 then n = 0; w("\n") end
end
w("0\n};\n\n")
w("static const struct { const char *name; int ofs; } libbc_map[] = {\n")
local m = 0
for _,name in ipairs(defs) do
w('{"'); w(name); w('",'); w(m) w('},\n')
m = m + #defs[name]
end
w("{NULL,"); w(m); w("}\n};\n\n")
return table.concat(t)
end
local function write_file(name, data)
if name == "-" then
assert(io.write(data))
assert(io.flush())
else
local fp = io.open(name)
if fp then
local old = fp:read("*a")
fp:close()
if data == old then return end
end
fp = assert(io.open(name, "w"))
assert(fp:write(data))
assert(fp:close())
end
end
local outfile = parse_arg(arg)
local src = read_files(arg)
local defs = find_defs(src)
local hdr = gen_header(defs)
write_file(outfile, hdr)
@@ -2,7 +2,7 @@
-- Lua script to generate a customized, minified version of Lua.
-- The resulting 'minilua' is used for the build process of LuaJIT.
----------------------------------------------------------------------------
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
@@ -210,6 +210,7 @@ typedef unsigned __int64 U64;
#else
typedef unsigned long long U64;
#endif
int _CRT_glob = 0;
]]}, {}
local function preprocess(src)
@@ -27,6 +27,7 @@ typedef unsigned __int64 U64;
#else
typedef unsigned long long U64;
#endif
int _CRT_glob = 0;
#include <stddef.h>
#include <stdarg.h>
#include <limits.h>
+1
View File
@@ -0,0 +1 @@
vmdef.lua
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT bytecode listing module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
@@ -41,7 +41,7 @@
-- Cache some library functions and objects.
local jit = require("jit")
assert(jit.version_num == 20001, "LuaJIT core/library version mismatch")
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local bit = require("bit")
@@ -179,13 +179,12 @@ local function bcliston(outfile)
end
-- Public module functions.
module(...)
line = bcline
dump = bcdump
targets = bctargets
on = bcliston
off = bclistoff
start = bcliston -- For -j command line option.
return {
line = bcline,
dump = bcdump,
targets = bctargets,
on = bcliston,
off = bclistoff,
start = bcliston -- For -j command line option.
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT module to save/list bytecode.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
@@ -11,7 +11,7 @@
------------------------------------------------------------------------------
local jit = require("jit")
assert(jit.version_num == 20001, "LuaJIT core/library version mismatch")
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
local bit = require("bit")
-- Symbol name prefix for LuaJIT bytecode.
@@ -63,13 +63,13 @@ local map_type = {
}
local map_arch = {
x86 = true, x64 = true, arm = true, ppc = true, ppcspe = true,
x86 = true, x64 = true, arm = true, arm64 = true, ppc = true,
mips = true, mipsel = true,
}
local map_os = {
linux = true, windows = true, osx = true, freebsd = true, netbsd = true,
openbsd = true, solaris = true,
openbsd = true, dragonfly = true, solaris = true,
}
local function checkarg(str, map, err)
@@ -200,9 +200,9 @@ typedef struct {
]]
local symname = LJBC_PREFIX..ctx.modname
local is64, isbe = false, false
if ctx.arch == "x64" then
if ctx.arch == "x64" or ctx.arch == "arm64" then
is64 = true
elseif ctx.arch == "ppc" or ctx.arch == "ppcspe" or ctx.arch == "mips" then
elseif ctx.arch == "ppc" or ctx.arch == "mips" then
isbe = true
end
@@ -237,7 +237,7 @@ typedef struct {
hdr.eendian = isbe and 2 or 1
hdr.eversion = 1
hdr.type = f16(1)
hdr.machine = f16(({ x86=3, x64=62, arm=40, ppc=20, ppcspe=20, mips=8, mipsel=8 })[ctx.arch])
hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
if ctx.arch == "mips" or ctx.arch == "mipsel" then
hdr.flags = 0x50001006
end
@@ -477,13 +477,13 @@ typedef struct {
} mach_obj_64;
typedef struct {
mach_fat_header fat;
mach_fat_arch fat_arch[4];
mach_fat_arch fat_arch[2];
struct {
mach_header hdr;
mach_segment_command seg;
mach_section sec;
mach_symtab_command sym;
} arch[4];
} arch[2];
mach_nlist sym_entry;
uint8_t space[4096];
} mach_fat_obj;
@@ -494,6 +494,8 @@ typedef struct {
is64, align, mobj = true, 8, "mach_obj_64"
elseif ctx.arch == "arm" then
isfat, mobj = true, "mach_fat_obj"
elseif ctx.arch == "arm64" then
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj"
else
check(ctx.arch == "x86", "unsupported architecture for OSX")
end
@@ -503,8 +505,8 @@ typedef struct {
-- Create Mach-O object and fill in header.
local o = ffi.new(mobj)
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12,12,12} })[ctx.arch]
local cpusubtype = ({ x86={3}, x64={3}, arm={3,6,9,11} })[ctx.arch]
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
if isfat then
o.fat.magic = be32(0xcafebabe)
o.fat.nfat_arch = be32(#cpusubtype)
@@ -653,7 +655,7 @@ end
------------------------------------------------------------------------------
-- Public module functions.
module(...)
start = docmd -- Process -b command line option.
return {
start = docmd -- Process -b command line option.
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT ARM disassembler module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
@@ -658,7 +658,7 @@ local function disass_block(ctx, ofs, len)
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create_(code, addr, out)
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
@@ -670,20 +670,20 @@ local function create_(code, addr, out)
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass_(code, addr, out)
create_(code, addr, out):disass()
local function disass(code, addr, out)
create(code, addr, out):disass()
end
-- Return register name for RID.
local function regname_(r)
local function regname(r)
if r < 16 then return map_gpr[r] end
return "d"..(r-16)
end
-- Public module functions.
module(...)
create = create_
disass = disass_
regname = regname_
return {
create = create,
disass = disass,
regname = regname
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS disassembler module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT/X license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
@@ -384,7 +384,7 @@ local function disass_block(ctx, ofs, len)
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create_(code, addr, out)
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
@@ -396,33 +396,33 @@ local function create_(code, addr, out)
return ctx
end
local function create_el_(code, addr, out)
local ctx = create_(code, addr, out)
local function create_el(code, addr, out)
local ctx = create(code, addr, out)
ctx.get = get_le
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass_(code, addr, out)
create_(code, addr, out):disass()
local function disass(code, addr, out)
create(code, addr, out):disass()
end
local function disass_el_(code, addr, out)
create_el_(code, addr, out):disass()
local function disass_el(code, addr, out)
create_el(code, addr, out):disass()
end
-- Return register name for RID.
local function regname_(r)
local function regname(r)
if r < 32 then return map_gpr[r] end
return "f"..(r-32)
end
-- Public module functions.
module(...)
create = create_
create_el = create_el_
disass = disass_
disass_el = disass_el_
regname = regname_
return {
create = create,
create_el = create_el,
disass = disass,
disass_el = disass_el,
regname = regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPSEL disassembler wrapper module.
--
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_el,
disass = dis_mips.disass_el,
regname = dis_mips.regname
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT PPC disassembler module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT/X license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
@@ -560,7 +560,7 @@ local function disass_block(ctx, ofs, len)
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create_(code, addr, out)
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
@@ -572,20 +572,20 @@ local function create_(code, addr, out)
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass_(code, addr, out)
create_(code, addr, out):disass()
local function disass(code, addr, out)
create(code, addr, out):disass()
end
-- Return register name for RID.
local function regname_(r)
local function regname(r)
if r < 32 then return map_gpr[r] end
return "f"..(r-32)
end
-- Public module functions.
module(...)
create = create_
disass = disass_
regname = regname_
return {
create = create,
disass = disass,
regname = regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT x64 disassembler wrapper module.
--
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the 64 bit functions from the combined
-- x86/x64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
return {
create = dis_x86.create64,
disass = dis_x86.disass64,
regname = dis_x86.regname64
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT x86/x64 disassembler module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
@@ -15,19 +15,20 @@
-- Intel and AMD manuals. The supported instruction set is quite extensive
-- and reflects what a current generation Intel or AMD CPU implements in
-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
-- SSE4.1, SSE4.2, SSE4a and even privileged and hypervisor (VMX/SVM)
-- instructions.
-- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor
-- (VMX/SVM) instructions.
--
-- Notes:
-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
-- * No attempt at optimization has been made -- it's fast enough for my needs.
-- * The public API may change when more architectures are added.
------------------------------------------------------------------------------
local type = type
local sub, byte, format = string.sub, string.byte, string.format
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
local lower, rep = string.lower, string.rep
local bit = require("bit")
local tohex = bit.tohex
-- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on.
local map_opc1_32 = {
@@ -76,7 +77,7 @@ local map_opc1_32 = {
"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
--Cx
"shift!Bmu","shift!Vmu","retBw","ret","$lesVrm","$ldsVrm","movBmi","movVmi",
"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
--Dx
"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
@@ -101,7 +102,7 @@ local map_opc1_64 = setmetatable({
[0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
[0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
[0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
[0x82]=false, [0x9a]=false, [0xc4]=false, [0xc5]=false, [0xce]=false,
[0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
[0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
}, { __index = map_opc1_32 })
@@ -112,12 +113,12 @@ local map_opc2 = {
[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
--1x
"movupsXrm|movssXrm|movupdXrm|movsdXrm",
"movupsXmr|movssXmr|movupdXmr|movsdXmr",
"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
"movlpsXmr||movlpdXmr",
"unpcklpsXrm||unpcklpdXrm",
"unpckhpsXrm||unpckhpdXrm",
"unpcklpsXrvm||unpcklpdXrvm",
"unpckhpsXrvm||unpckhpdXrvm",
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
"movhpsXmr||movhpdXmr",
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
@@ -126,7 +127,7 @@ local map_opc2 = {
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
"movapsXrm||movapdXrm",
"movapsXmr||movapdXmr",
"cvtpi2psXrMm|cvtsi2ssXrVmt|cvtpi2pdXrMm|cvtsi2sdXrVmt",
"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
@@ -142,27 +143,27 @@ local map_opc2 = {
"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
--5x
"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm",
"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm",
"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm",
"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm",
"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm",
"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
--6x
"punpcklbwPrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
"||punpcklqdqXrm","||punpckhqdqXrm",
"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
"||punpcklqdqXrvm","||punpckhqdqXrvm",
"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
--7x
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu",
"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
nil,nil,
"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
--8x
"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
@@ -180,27 +181,27 @@ nil,nil,
"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
--Cx
"xaddBmr","xaddVmr",
"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","$movntiVmr|",
"pinsrwPrWmu","pextrwDrPmu",
"shufpsXrmu||shufpdXrmu","$cmpxchg!Qmp",
"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
"pinsrwPrvWmu","pextrwDrPmu",
"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
--Dx
"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
"paddqPrm","pmullwPrm",
"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
"paddqPrvm","pmullwPrvm",
"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
--Ex
"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
"pmulhuwPrm","pmulhwPrm",
"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
"pmulhuwPrvm","pmulhwPrvm",
"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
"psubsbPrm","psubswPrm","pminswPrm","porPrm",
"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
--Fx
"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm$",
"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
"paddbPrm","paddwPrm","padddPrm","ud",
"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
"paddbPrvm","paddwPrvm","padddPrvm","ud",
}
assert(map_opc2[255] == "ud")
@@ -208,46 +209,62 @@ assert(map_opc2[255] == "ud")
local map_opc3 = {
["38"] = { -- [66] 0f 38 xx
--0x
[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
nil,nil,nil,nil,
[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
"||permilpsXrvm","||permilpdXrvm",nil,nil,
--1x
"||pblendvbXrma",nil,nil,nil,
"||blendvpsXrma","||blendvpdXrma",nil,"||ptestXrm",
nil,nil,nil,nil,
"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
"pabsbPrm","pabswPrm","pabsdPrm",nil,
--2x
"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
"||pmuldqXrm","||pcmpeqqXrm","||$movntdqaXrm","||packusdwXrm",
nil,nil,nil,nil,
"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
--3x
"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
"||pmovzxwqXrm","||pmovzxdqXrm",nil,"||pcmpgtqXrm",
"||pminsbXrm","||pminsdXrm","||pminuwXrm","||pminudXrm",
"||pmaxsbXrm","||pmaxsdXrm","||pmaxuwXrm","||pmaxudXrm",
"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
--4x
"||pmulddXrm","||phminposuwXrm",
"||pmulddXrvm","||phminposuwXrm",nil,nil,
nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
--5x
[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
[0x5a] = "||broadcasti128XrlXm",
--7x
[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
--8x
[0x8c] = "||pmaskmovXrvVSm",
[0x8e] = "||pmaskmovVSmXvr",
--Fx
[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
},
["3a"] = { -- [66] 0f 3a xx
--0x
[0x00]=nil,nil,nil,nil,nil,nil,nil,nil,
"||roundpsXrmu","||roundpdXrmu","||roundssXrmu","||roundsdXrmu",
"||blendpsXrmu","||blendpdXrmu","||pblendwXrmu","palignrPrmu",
[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
--1x
nil,nil,nil,nil,
"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
nil,nil,nil,nil,nil,nil,nil,nil,
"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
nil,nil,nil,nil,
--2x
"||pinsrbXrVmu","||insertpsXrmu","||pinsrXrVmuS",nil,
"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
--3x
[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
--4x
[0x40] = "||dppsXrmu",
[0x41] = "||dppdXrmu",
[0x42] = "||mpsadbwXrmu",
[0x40] = "||dppsXrvmu",
[0x41] = "||dppdXrvmu",
[0x42] = "||mpsadbwXrvmu",
[0x46] = "||perm2i128Xrvmu",
[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
[0x4c] = "||pblendvbXrvmb",
--6x
[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
@@ -354,17 +371,19 @@ local map_regs = {
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
}
local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
-- Maps for size names.
local map_sz2n = {
B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16,
B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
}
local map_sz2prefix = {
B = "byte", W = "word", D = "dword",
Q = "qword",
M = "qword", X = "xword",
M = "qword", X = "xword", Y = "yword",
F = "dword", G = "qword", -- No need for sizes/register names for these two.
}
@@ -387,10 +406,13 @@ local function putop(ctx, text, operands)
if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
if ctx.rex then
local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")
if t ~= "" then text = "rex."..t.." "..text end
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
(ctx.vexl and "l" or "")
if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
if t ~= "" then text = ctx.rex.."."..t.." "..text
elseif ctx.rex == "vex" then text = "v"..text end
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false
ctx.rex = false; ctx.vexl = false; ctx.vexv = false
end
if ctx.seg then
local text2, n = gsub(text, "%[", "["..ctx.seg..":")
@@ -405,6 +427,7 @@ local function putop(ctx, text, operands)
end
ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
ctx.mrm = false
ctx.vexv = false
ctx.start = pos
ctx.imm = nil
end
@@ -413,7 +436,7 @@ end
local function clearprefixes(ctx)
ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false; ctx.a32 = false
ctx.rex = false; ctx.a32 = false; ctx.vexl = false
end
-- Fallback for incomplete opcodes at the end.
@@ -450,9 +473,9 @@ end
-- Process pattern string and generate the operands.
local function putpat(ctx, name, pat)
local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
local code, pos, stop = ctx.code, ctx.pos, ctx.stop
local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
-- Chars used: 1DFGIMPQRSTUVWXacdfgijmoprstuwxyz
-- Chars used: 1DFGIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
for p in gmatch(pat, ".") do
local x = nil
if p == "V" or p == "U" then
@@ -467,11 +490,13 @@ local function putpat(ctx, name, pat)
elseif p == "B" then
sz = "B"
regs = ctx.rex and map_regs.B64 or map_regs.B
elseif match(p, "[WDQMXFG]") then
elseif match(p, "[WDQMXYFG]") then
sz = p
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz]
elseif p == "P" then
sz = ctx.o16 and "X" or "M"; ctx.o16 = false
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz]
elseif p == "S" then
name = name..lower(sz)
@@ -484,6 +509,10 @@ local function putpat(ctx, name, pat)
local imm = getimm(ctx, pos, 1); if not imm then return end
x = format("0x%02x", imm)
pos = pos+1
elseif p == "b" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = regs[imm/16+1]
pos = pos+1
elseif p == "w" then
local imm = getimm(ctx, pos, 2); if not imm then return end
x = format("0x%x", imm)
@@ -532,7 +561,7 @@ local function putpat(ctx, name, pat)
local lo = imm % 0x1000000
x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo)
else
x = format("0x%08x", imm)
x = "0x"..tohex(imm)
end
elseif p == "R" then
local r = byte(code, pos-1, pos-1)%8
@@ -616,8 +645,13 @@ local function putpat(ctx, name, pat)
else
x = "CR"..sp
end
elseif p == "v" then
if ctx.vexv then
x = regs[ctx.vexv+1]; ctx.vexv = false
end
elseif p == "y" then x = "DR"..sp
elseif p == "z" then x = "TR"..sp
elseif p == "l" then vexl = false
elseif p == "t" then
else
error("bad pattern `"..pat.."'")
@@ -692,7 +726,7 @@ map_act = {
B = putpat, W = putpat, D = putpat, Q = putpat,
V = putpat, U = putpat, T = putpat,
M = putpat, X = putpat, P = putpat,
F = putpat, G = putpat,
F = putpat, G = putpat, Y = putpat,
-- Collect prefixes.
[":"] = function(ctx, name, pat)
@@ -753,15 +787,68 @@ map_act = {
-- REX prefix.
rex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX prefix allowed.
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
for p in gmatch(pat, ".") do ctx["rex"..p] = true end
ctx.rex = true
ctx.rex = "rex"
end,
-- VEX prefix.
vex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
ctx.rex = "vex"
local pos = ctx.pos
if ctx.mrm then
ctx.mrm = nil
pos = pos-1
end
local b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b < 128 then ctx.rexr = true end
local m = 1
if pat == "3" then
m = b%32; b = (b-m)/32
local nb = b%2; b = (b-nb)/2
if nb == 0 then ctx.rexb = true end
local nx = b%2; b = (b-nx)/2
if nx == 0 then ctx.rexx = true end
b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b >= 128 then ctx.rexw = true end
end
ctx.pos = pos
local map
if m == 1 then map = map_opc2
elseif m == 2 then map = map_opc3["38"]
elseif m == 3 then map = map_opc3["3a"]
else return unknown(ctx) end
local p = b%4; b = (b-p)/4
if p == 1 then ctx.o16 = "o16"
elseif p == 2 then ctx.rep = "rep"
elseif p == 3 then ctx.rep = "repne" end
local l = b%2; b = (b-l)/2
if l ~= 0 then ctx.vexl = true end
ctx.vexv = (-1-b)%16
return dispatchmap(ctx, map)
end,
-- Special case for nop with REX prefix.
nop = function(ctx, name, pat)
return dispatch(ctx, ctx.rex and pat or "nop")
end,
-- Special case for 0F 77.
emms = function(ctx, name, pat)
if ctx.rex ~= "vex" then
return putop(ctx, "emms")
elseif ctx.vexl then
ctx.vexl = false
return putop(ctx, "zeroall")
else
return putop(ctx, "zeroupper")
end
end,
}
------------------------------------------------------------------------------
@@ -782,7 +869,7 @@ local function disass_block(ctx, ofs, len)
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create_(code, addr, out)
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = (addr or 0) - 1
@@ -796,8 +883,8 @@ local function create_(code, addr, out)
return ctx
end
local function create64_(code, addr, out)
local ctx = create_(code, addr, out)
local function create64(code, addr, out)
local ctx = create(code, addr, out)
ctx.x64 = true
ctx.map1 = map_opc1_64
ctx.aregs = map_regs.Q
@@ -805,32 +892,32 @@ local function create64_(code, addr, out)
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass_(code, addr, out)
create_(code, addr, out):disass()
local function disass(code, addr, out)
create(code, addr, out):disass()
end
local function disass64_(code, addr, out)
create64_(code, addr, out):disass()
local function disass64(code, addr, out)
create64(code, addr, out):disass()
end
-- Return register name for RID.
local function regname_(r)
local function regname(r)
if r < 8 then return map_regs.D[r+1] end
return map_regs.X[r-7]
end
local function regname64_(r)
local function regname64(r)
if r < 16 then return map_regs.Q[r+1] end
return map_regs.X[r-15]
end
-- Public module functions.
module(...)
create = create_
create64 = create64_
disass = disass_
disass64 = disass64_
regname = regname_
regname64 = regname64_
return {
create = create,
create64 = create64,
disass = disass,
disass64 = disass64,
regname = regname,
regname64 = regname64
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- LuaJIT compiler dump module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
@@ -36,6 +36,7 @@
-- * m Dump the generated machine code.
-- x Print each taken trace exit.
-- X Print each taken trace exit and the contents of all registers.
-- a Print the IR of aborted traces, too.
--
-- The output format can be set with the following characters:
--
@@ -54,7 +55,7 @@
-- Cache some library functions and objects.
local jit = require("jit")
assert(jit.version_num == 20001, "LuaJIT core/library version mismatch")
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
@@ -62,7 +63,7 @@ local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
local bit = require("bit")
local band, shl, shr = bit.band, bit.lshift, bit.rshift
local band, shl, shr, tohex = bit.band, bit.lshift, bit.rshift, bit.tohex
local sub, gsub, format = string.sub, string.gsub, string.format
local byte, char, rep = string.byte, string.char, string.rep
local type, tostring = type, tostring
@@ -90,6 +91,7 @@ local function fillsymtab_tr(tr, nexit)
end
for i=0,nexit-1 do
local addr = traceexitstub(tr, i)
if addr < 0 then addr = addr + 2^32 end
t[addr] = tostring(i)
end
local addr = traceexitstub(tr, nexit)
@@ -103,7 +105,10 @@ local function fillsymtab(tr, nexit)
local ircall = vmdef.ircall
for i=0,#ircall do
local addr = ircalladdr(i)
if addr ~= 0 then t[addr] = ircall[i] end
if addr ~= 0 then
if addr < 0 then addr = addr + 2^32 end
t[addr] = ircall[i]
end
end
end
if nexitsym == 1000000 then -- Per-trace exit stubs.
@@ -117,6 +122,7 @@ local function fillsymtab(tr, nexit)
nexit = 1000000
break
end
if addr < 0 then addr = addr + 2^32 end
t[addr] = tostring(i)
end
nexitsym = nexit
@@ -135,6 +141,7 @@ local function dump_mcode(tr)
local mcode, addr, loop = tracemc(tr)
if not mcode then return end
if not disass then disass = require("jit.dis_"..jit.arch) end
if addr < 0 then addr = addr + 2^32 end
out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
local ctx = disass.create(mcode, addr, dumpwrite)
ctx.hexdump = 0
@@ -269,8 +276,7 @@ local litname = {
["CONV "] = setmetatable({}, { __index = function(t, mode)
local s = irtype[band(mode, 31)]
s = irtype[band(shr(mode, 5), 31)].."."..s
if band(mode, 0x400) ~= 0 then s = s.." trunc"
elseif band(mode, 0x800) ~= 0 then s = s.." sext" end
if band(mode, 0x800) ~= 0 then s = s.." sext" end
local c = shr(mode, 14)
if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
t[mode] = s
@@ -279,6 +285,8 @@ local litname = {
["FLOAD "] = vmdef.irfield,
["FREF "] = vmdef.irfield,
["FPMATH"] = vmdef.irfpm,
["BUFHDR"] = { [0] = "RESET", "APPEND" },
["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
}
local function ctlsub(c)
@@ -546,10 +554,8 @@ local function dump_trace(what, tr, func, pc, otr, oex)
out:write("---- TRACE ", tr, " ", what)
if otr then out:write(" ", otr, "/", oex) end
out:write(" ", fmtfunc(func, pc), "\n")
recprefix = ""
elseif what == "stop" or what == "abort" then
out:write("---- TRACE ", tr, " ", what)
recprefix = nil
if what == "abort" then
out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
else
@@ -565,6 +571,7 @@ local function dump_trace(what, tr, func, pc, otr, oex)
end
if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
else
if what == "flush" then symtab, nexitsym = {}, 0 end
out:write("---- TRACE ", what, "\n\n")
end
out:flush()
@@ -608,7 +615,7 @@ local function dump_texit(tr, ex, ngpr, nfpr, ...)
end
else
for i=1,ngpr do
out:write(format(" %08x", regs[i]))
out:write(" ", tohex(regs[i]))
if i % 8 == 0 then out:write("\n") end
end
end
@@ -692,9 +699,9 @@ local function dumpon(opt, outfile)
end
-- Public module functions.
module(...)
on = dumpon
off = dumpoff
start = dumpon -- For -j command line option.
return {
on = dumpon,
off = dumpoff,
start = dumpon -- For -j command line option.
}
+310
View File
@@ -0,0 +1,310 @@
----------------------------------------------------------------------------
-- LuaJIT profiler.
--
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module is a simple command line interface to the built-in
-- low-overhead profiler of LuaJIT.
--
-- The lower-level API of the profiler is accessible via the "jit.profile"
-- module or the luaJIT_profile_* C API.
--
-- Example usage:
--
-- luajit -jp myapp.lua
-- luajit -jp=s myapp.lua
-- luajit -jp=-s myapp.lua
-- luajit -jp=vl myapp.lua
-- luajit -jp=G,profile.txt myapp.lua
--
-- The following dump features are available:
--
-- f Stack dump: function name, otherwise module:line. Default mode.
-- F Stack dump: ditto, but always prepend module.
-- l Stack dump: module:line.
-- <number> stack dump depth (callee < caller). Default: 1.
-- -<number> Inverse stack dump depth (caller > callee).
-- s Split stack dump after first stack level. Implies abs(depth) >= 2.
-- p Show full path for module names.
-- v Show VM states. Can be combined with stack dumps, e.g. vf or fv.
-- z Show zones. Can be combined with stack dumps, e.g. zf or fz.
-- r Show raw sample counts. Default: show percentages.
-- a Annotate excerpts from source code files.
-- A Annotate complete source code files.
-- G Produce raw output suitable for graphical tools (e.g. flame graphs).
-- m<number> Minimum sample percentage to be shown. Default: 3.
-- i<number> Sampling interval in milliseconds. Default: 10.
--
----------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
local profile = require("jit.profile")
local vmdef = require("jit.vmdef")
local math = math
local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor
local sort, format = table.sort, string.format
local stdout = io.stdout
local zone -- Load jit.zone module on demand.
-- Output file handle.
local out
------------------------------------------------------------------------------
local prof_ud
local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth
local prof_ann, prof_count1, prof_count2, prof_samples
local map_vmmode = {
N = "Compiled",
I = "Interpreted",
C = "C code",
G = "Garbage Collector",
J = "JIT Compiler",
}
-- Profiler callback.
local function prof_cb(th, samples, vmmode)
prof_samples = prof_samples + samples
local key_stack, key_stack2, key_state
-- Collect keys for sample.
if prof_states then
if prof_states == "v" then
key_state = map_vmmode[vmmode] or vmmode
else
key_state = zone:get() or "(none)"
end
end
if prof_fmt then
key_stack = profile.dumpstack(th, prof_fmt, prof_depth)
key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x)
return vmdef.ffnames[tonumber(x)]
end)
if prof_split == 2 then
local k1, k2 = key_stack:match("(.-) [<>] (.*)")
if k2 then key_stack, key_stack2 = k1, k2 end
elseif prof_split == 3 then
key_stack2 = profile.dumpstack(th, "l", 1)
end
end
-- Order keys.
local k1, k2
if prof_split == 1 then
if key_state then
k1 = key_state
if key_stack then k2 = key_stack end
end
elseif key_stack then
k1 = key_stack
if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end
end
-- Coalesce samples in one or two levels.
if k1 then
local t1 = prof_count1
t1[k1] = (t1[k1] or 0) + samples
if k2 then
local t2 = prof_count2
local t3 = t2[k1]
if not t3 then t3 = {}; t2[k1] = t3 end
t3[k2] = (t3[k2] or 0) + samples
end
end
end
------------------------------------------------------------------------------
-- Show top N list.
local function prof_top(count1, count2, samples, indent)
local t, n = {}, 0
for k, v in pairs(count1) do
n = n + 1
t[n] = k
end
sort(t, function(a, b) return count1[a] > count1[b] end)
for i=1,n do
local k = t[i]
local v = count1[k]
local pct = floor(v*100/samples + 0.5)
if pct < prof_min then break end
if not prof_raw then
out:write(format("%s%2d%% %s\n", indent, pct, k))
elseif prof_raw == "r" then
out:write(format("%s%5d %s\n", indent, v, k))
else
out:write(format("%s %d\n", k, v))
end
if count2 then
local r = count2[k]
if r then
prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or
(prof_depth < 0 and " -> " or " <- "))
end
end
end
end
-- Annotate source code
local function prof_annotate(count1, samples)
local files = {}
local ms = 0
for k, v in pairs(count1) do
local pct = floor(v*100/samples + 0.5)
ms = math.max(ms, v)
if pct >= prof_min then
local file, line = k:match("^(.*):(%d+)$")
local fl = files[file]
if not fl then fl = {}; files[file] = fl; files[#files+1] = file end
line = tonumber(line)
fl[line] = prof_raw and v or pct
end
end
sort(files)
local fmtv, fmtn = " %3d%% | %s\n", " | %s\n"
if prof_raw then
local n = math.max(5, math.ceil(math.log10(ms)))
fmtv = "%"..n.."d | %s\n"
fmtn = (" "):rep(n).." | %s\n"
end
local ann = prof_ann
for _, file in ipairs(files) do
local f0 = file:byte()
if f0 == 40 or f0 == 91 then
out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file))
break
end
local fp, err = io.open(file)
if not fp then
out:write(format("====== ERROR: %s: %s\n", file, err))
break
end
out:write(format("\n====== %s ======\n", file))
local fl = files[file]
local n, show = 1, false
if ann ~= 0 then
for i=1,ann do
if fl[i] then show = true; out:write("@@ 1 @@\n"); break end
end
end
for line in fp:lines() do
if line:byte() == 27 then
out:write("[Cannot annotate bytecode file]\n")
break
end
local v = fl[n]
if ann ~= 0 then
local v2 = fl[n+ann]
if show then
if v2 then show = n+ann elseif v then show = n
elseif show+ann < n then show = false end
elseif v2 then
show = n+ann
out:write(format("@@ %d @@\n", n))
end
if not show then goto next end
end
if v then
out:write(format(fmtv, v, line))
else
out:write(format(fmtn, line))
end
::next::
n = n + 1
end
fp:close()
end
end
------------------------------------------------------------------------------
-- Finish profiling and dump result.
local function prof_finish()
if prof_ud then
profile.stop()
local samples = prof_samples
if samples == 0 then
if prof_raw ~= true then out:write("[No samples collected]\n") end
return
end
if prof_ann then
prof_annotate(prof_count1, samples)
else
prof_top(prof_count1, prof_count2, samples, "")
end
prof_count1 = nil
prof_count2 = nil
prof_ud = nil
end
end
-- Start profiling.
local function prof_start(mode)
local interval = ""
mode = mode:gsub("i%d*", function(s) interval = s; return "" end)
prof_min = 3
mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end)
prof_depth = 1
mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end)
local m = {}
for c in mode:gmatch(".") do m[c] = c end
prof_states = m.z or m.v
if prof_states == "z" then zone = require("jit.zone") end
local scope = m.l or m.f or m.F or (prof_states and "" or "f")
local flags = (m.p or "")
prof_raw = m.r
if m.s then
prof_split = 2
if prof_depth == -1 or m["-"] then prof_depth = -2
elseif prof_depth == 1 then prof_depth = 2 end
elseif mode:find("[fF].*l") then
scope = "l"
prof_split = 3
else
prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0
end
prof_ann = m.A and 0 or (m.a and 3)
if prof_ann then
scope = "l"
prof_fmt = "pl"
prof_split = 0
prof_depth = 1
elseif m.G and scope ~= "" then
prof_fmt = flags..scope.."Z;"
prof_depth = -100
prof_raw = true
prof_min = 0
elseif scope == "" then
prof_fmt = false
else
local sc = prof_split == 3 and m.f or m.F or scope
prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ")
end
prof_count1 = {}
prof_count2 = {}
prof_samples = 0
profile.start(scope:lower()..interval, prof_cb)
prof_ud = newproxy(true)
getmetatable(prof_ud).__gc = prof_finish
end
------------------------------------------------------------------------------
local function start(mode, outfile)
if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stdout
end
prof_start(mode or "f")
end
-- Public module functions.
return {
start = start, -- For -j command line option.
stop = prof_finish
}
@@ -1,7 +1,7 @@
----------------------------------------------------------------------------
-- Verbose mode of the LuaJIT compiler.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
@@ -59,7 +59,7 @@
-- Cache some library functions and objects.
local jit = require("jit")
assert(jit.version_num == 20001, "LuaJIT core/library version mismatch")
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
@@ -116,6 +116,9 @@ local function dump_trace(what, tr, func, pc, otr, oex)
if ltype == "interpreter" then
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
tr, startex, startloc))
elseif ltype == "stitch" then
out:write(format("[TRACE %3s %s%s %s %s]\n",
tr, startex, startloc, ltype, fmtfunc(func, pc)))
elseif link == tr or link == 0 then
out:write(format("[TRACE %3s %s%s %s]\n",
tr, startex, startloc, ltype))
@@ -159,9 +162,9 @@ local function dumpon(outfile)
end
-- Public module functions.
module(...)
on = dumpon
off = dumpoff
start = dumpon -- For -j command line option.
return {
on = dumpon,
off = dumpoff,
start = dumpon -- For -j command line option.
}
+45
View File
@@ -0,0 +1,45 @@
----------------------------------------------------------------------------
-- LuaJIT profiler zones.
--
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module implements a simple hierarchical zone model.
--
-- Example usage:
--
-- local zone = require("jit.zone")
-- zone("AI")
-- ...
-- zone("A*")
-- ...
-- print(zone:get()) --> "A*"
-- ...
-- zone()
-- ...
-- print(zone:get()) --> "AI"
-- ...
-- zone()
--
----------------------------------------------------------------------------
local remove = table.remove
return setmetatable({
flush = function(t)
for i=#t,1,-1 do t[i] = nil end
end,
get = function(t)
return t[#t]
end
}, {
__call = function(t, zone)
if zone then
t[#t+1] = zone
else
return (assert(remove(t), "empty zone stack"))
end
end
})

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