├── .gitignore ├── .gitmodules ├── .travis.yml ├── CONTRIBUTING.md ├── Makefile ├── README.md ├── README_zh.md ├── doc ├── building.md ├── lua_vermelha.md ├── lvjit_api.md └── zh │ ├── building.md │ ├── lua_vermelha.md │ └── lvjit_api.md ├── lua ├── Makefile ├── lapi.c ├── lapi.h ├── lauxlib.c ├── lauxlib.h ├── lbaselib.c ├── lbitlib.c ├── lcode.c ├── lcode.h ├── lcorolib.c ├── lctype.c ├── lctype.h ├── ldblib.c ├── ldebug.c ├── ldebug.h ├── ldo.c ├── ldo.h ├── ldump.c ├── lfunc.c ├── lfunc.h ├── lgc.c ├── lgc.h ├── linit.c ├── liolib.c ├── llex.c ├── llex.h ├── llimits.h ├── lmathlib.c ├── lmem.c ├── lmem.h ├── loadlib.c ├── lobject.c ├── lobject.h ├── lopcodes.c ├── lopcodes.h ├── loslib.c ├── lparser.c ├── lparser.h ├── lprefix.h ├── lstate.c ├── lstate.h ├── lstring.c ├── lstring.h ├── lstrlib.c ├── ltable.c ├── ltable.h ├── ltablib.c ├── ltm.c ├── ltm.h ├── lua.c ├── lua.h ├── lua.hpp ├── luac.c ├── luaconf.h ├── lualib.h ├── luav.h ├── lundump.c ├── lundump.h ├── lutf8lib.c ├── lvapi.c ├── lvapi.h ├── lvjit.h ├── lvjitlib.c ├── lvm.c ├── lvm.h ├── lzio.c └── lzio.h ├── lvjit ├── LuaFunctionBuilder.cpp ├── LuaFunctionBuilder.hpp ├── LuaTypeDictionary.cpp ├── LuaTypeDictionary.hpp ├── Makefile ├── luavm.hpp └── lvjit.cpp └── test ├── README.md ├── README_zh.md ├── benchmark ├── loop_add_double_register_with_double_constants.lua ├── loop_add_double_register_with_int_constants.lua ├── loop_add_int_constant_with_int_register.lua ├── loop_add_int_register_with_double_constants.lua └── loop_add_int_register_with_int_constants.lua ├── control ├── all.lua ├── initcounter.lua ├── jit_blacklist.lua ├── jit_compile.lua ├── jitflags.lua └── lvjitlib_compile.lua ├── lvjit ├── .gitignore ├── Makefile ├── compile_test.cpp ├── initcounter_test.cpp └── jitflags_test.cpp └── opcode ├── all.lua ├── arithmetic.lua ├── asserts.lua ├── booleans.lua ├── call.lua ├── closure.lua ├── comparisons.lua ├── concat.lua ├── forloop.lua ├── goto.lua ├── loads.lua ├── move.lua ├── return.lua ├── self.lua ├── setlist.lua ├── tables.lua ├── tailcall.lua ├── tforloop.lua ├── upvalue.lua ├── upvaluetable.lua └── varargs.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.a 4 | *.swp 5 | lua/lua 6 | lua/luac 7 | luav 8 | 9 | # Qt Creator files 10 | LuaVermelha.config 11 | LuaVermelha.creator 12 | LuaVermelha.files 13 | LuaVermelha.includes 14 | *.user 15 | 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "omr"] 2 | path = omr 3 | url = https://github.com/eclipse/omr 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | os: linux 3 | sudo: required 4 | dist: trusty 5 | 6 | addons: 7 | apt: 8 | sources: 9 | # add PPAs with more up-to-date toolchains 10 | - ubuntu-toolchain-r-test 11 | # - llvm-toolchain-precise-3.8 12 | packages: 13 | # install toolchains 14 | - gcc-5 15 | - g++-5 16 | # - clang-3.8 17 | 18 | compiler: gcc-5 19 | 20 | install: true 21 | 22 | script: cd omr && make -f run_configure.mk SPEC=linux_x86-64 OMRGLUE=./example/glue && cd .. && make && make test 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha Contribution guidelines 2 | 3 | There are several ways you can help make Lua Vermelha better. 4 | For example, you can: 5 | 6 | * open an issue to: 7 | * report a bug 8 | * create a feature request 9 | * suggest an improvement, e.g.: 10 | * code cleanup 11 | * better documentation 12 | * open a pull request to: 13 | * fix a bug 14 | * add a new feature 15 | * improve code quality/readability 16 | * add or improve testing 17 | * add or improve documentation 18 | * review and comment on open issues and pull requests 19 | 20 | ## Opening an Issue 21 | 22 | When opening an issue: 23 | 24 | * give the issue a short, meaningful name 25 | * provide as much detail as you can in the description, e.g.: 26 | * what you did when you found a bug 27 | * what platform/environment you were running on when you found a bug 28 | * how does some new feature improve Lua Vemrelha 29 | * why is a new improvement beneficial 30 | * what changes have to be made to accomplish the improvement 31 | * understand that the point of opening an issue is to start a discussion 32 | * expect questions and/or feedback 33 | 34 | ## Opening a Pull Request 35 | 36 | When opening a pull request (PR): 37 | 38 | * give the PR a short, meaningful name 39 | * write a detailed description of what your changes are and what they do 40 | * provide some justification for your changes, e.g.: 41 | * link to an open issue 42 | * write good commit messages: 43 | * the first line should be a clear, short (50 characters or less) description 44 | of what the commit changes, written in the imperative 45 | * the one-line description should be followed by a blank line, and then by a 46 | more comprehensive description of the commit 47 | * if appropriate, use GitHub flavoured Markdown in the longer description 48 | * the commit message should be wrapped at 72 characters 49 | * put relevant commit meta-data at the end of the pull-request, e.g.: 50 | * `Fixes #1234` 51 | * make sure any new code is sufficiently documented 52 | * make sure that documentation is clear and understandable 53 | * make sure that non-trivial code changes get tested 54 | * try to keep the PR and commits not too large (split them up if needed) 55 | * understand that the point of opening a PR is to get your changes reviewed 56 | * expect questions and/or feedback 57 | 58 | ## Commenting on Issues and Pull Requests 59 | 60 | When commenting on an open issue or PR: 61 | 62 | * be respectful 63 | * be clear so that others will understand you 64 | * when replaying to another person, @mention them so everyone knows who you're 65 | writing to 66 | 67 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # (c) Copyright IBM Corp. 2016, 2017 4 | # 5 | # This program and the accompanying materials are made available 6 | # under the terms of the Eclipse Public License v1.0 and 7 | # Apache License v2.0 which accompanies this distribution. 8 | # 9 | # The Eclipse Public License is available at 10 | # http://www.eclipse.org/legal/epl-v10.html 11 | # 12 | # The Apache License v2.0 is available at 13 | # http://www.opensource.org/licenses/apache2.0.php 14 | # 15 | # Contributors: 16 | # Multiple authors (IBM Corp.) - initial implementation and documentation 17 | # 18 | ################################################################################ 19 | 20 | CC?= gcc 21 | CXX?= g++ 22 | 23 | BUILD_CONFIG?= opt 24 | 25 | ifeq ($(BUILD_CONFIG),debug) 26 | LUA_BUILD_CONFIG_FLAGS= -O0 -g 27 | LVJIT_BUILD_CONFIG_FLAGS= -O0 -g 28 | JITBUILDER_BUILD_CONFIG_FLAGS= -O0 -g 29 | JITBUILDER_BUILD_CONFIG_VARS= BUILD_CONFIG=debug 30 | else ifeq ($(BUILD_CONFIG),opt) 31 | LUA_BUILD_CONFIG_FLAGS= -O2 -g 32 | LVJIT_BUILD_CONFIG_FLAGS= -O3 -g 33 | JITBUILDER_BUILD_CONFIG_FLAGS= -O3 -g 34 | JITBUILDER_BUILD_CONFIG_VARS= 35 | else ifeq ($(BUILD_CONFIG),prod) 36 | LUA_BUILD_CONFIG_FLAGS= -O2 37 | LVJIT_BUILD_CONFIG_FLAGS= -O3 38 | JITBUILDER_BUILD_CONFIG_FLAGS= -O3 39 | JITBUILDER_BUILD_CONFIG_VARS= BUILD_CONFIG=prod ASSUMES= 40 | endif 41 | 42 | LUAV?= luav 43 | 44 | LUA_APP?= lua.o 45 | LUA_LIB?= liblua.a 46 | LVJIT_LIB?= liblvjit.a 47 | JITBUILDER_LIB?= libjitbuilder.a 48 | 49 | LUA_DIR?= $(PWD)/lua 50 | LVJIT_DIR?= $(PWD)/lvjit 51 | JITBUILDER_DIR?= $(PWD)/omr/jitbuilder 52 | 53 | LUA_LIBPATH?= $(LUA_DIR)/$(LUA_LIB) 54 | LVJIT_LIBPATH?= $(LVJIT_DIR)/$(LVJIT_LIB) 55 | JITBUILDER_LIBPATH?= $(JITBUILDER_DIR)/release/$(JITBUILDER_LIB) 56 | 57 | 58 | # targets 59 | 60 | .PHONY: all $(LUA_DIR)/lua.o $(LUA_LIBPATH) $(LVJIT_LIBPATH) $(JITBUILDER_LIBPATH) 61 | 62 | all: $(LUAV) 63 | 64 | 65 | $(LUAV): $(LUA_DIR)/lua.o $(LUA_LIBPATH) $(LVJIT_LIBPATH) $(JITBUILDER_LIBPATH) 66 | $(CXX) -o $@ $(LUA_DIR)/lua.o $(LUA_LIBPATH) $(LVJIT_LIBPATH) $(JITBUILDER_LIBPATH) -ldl -lm -lreadline 67 | 68 | $(LUA_DIR)/lua.o: 69 | cd $(LUA_DIR) && $(MAKE) lua.o SYSCFLAGS="-DLUA_USE_LINUX" MYCFLAGS="$(LUA_BUILD_CONFIG_FLAGS)" 70 | $(LUA_LIBPATH): 71 | cd $(LUA_DIR) && $(MAKE) $(LUA_LIB) SYSCFLAGS="-DLUA_USE_LINUX" MYCFLAGS="$(LUA_BUILD_CONFIG_FLAGS)" 72 | 73 | $(LVJIT_LIBPATH): 74 | cd $(LVJIT_DIR) && $(MAKE) $@ CXX="$(CXX)" CXX_FLAGS_EXTRA="-fpermissive -DLUA_C_LINKAGE $(LVJIT_BUILD_CONFIG_FLAGS)" 75 | 76 | $(JITBUILDER_LIBPATH): 77 | cd $(JITBUILDER_DIR) && $(MAKE) CXX="$(CXX)" CXX_FLAGS_EXTRA="$(JITBUILDER_BUILD_CONFIG_FLAGS)" $(JITBUILDER_BUILD_CONFIG_VARS) 78 | 79 | 80 | # clean rules 81 | 82 | clean: 83 | cd $(LUA_DIR) && $(MAKE) clean 84 | cd $(LVJIT_DIR) && $(MAKE) clean 85 | 86 | cleanlibs: 87 | rm -f $(LUA_DIR)/lua.o $(LUA_LIBPATH) $(LVJIT_LIBPATH) $(JITBUILDER_LIBPATH) 88 | 89 | cleanlua: 90 | cd $(LUA_DIR) && $(MAKE) clean 91 | 92 | cleanlvjit: 93 | cd $(LVJIT_DIR) && $(MAKE) cleanall 94 | 95 | cleanjitbuilder: 96 | cd $(JITBUILDER_DIR) && $(MAKE) clean 97 | 98 | cleanall: 99 | cd $(LUA_DIR) && $(MAKE) clean 100 | cd $(LVJIT_DIR) && $(MAKE) cleanall 101 | cd $(JITBUILDER_DIR) && $(MAKE) clean 102 | 103 | # test rules 104 | 105 | .PHONY: test 106 | 107 | test: 108 | cd test/lvjit && make 109 | cd test/control && ../../$(LUAV) all.lua 110 | cd test/opcode && ../../$(LUAV) all.lua 111 | 112 | # lua patch 113 | 114 | # version of lua to diff against 115 | LUA?=luavm 116 | 117 | # commit with the applied changes 118 | COMMIT?=HEAD 119 | 120 | PATCH_DEST?=$(PWD) 121 | PATCH_FILE?=$(LUA)-$(COMMIT).patch 122 | 123 | lua-patch: 124 | git diff $(LUA) $(COMMIT) -- lua/* > $(PATCH_DEST)/$(PATCH_FILE) 125 | 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha 2 | 3 | [![Build Status](https://travis-ci.org/Leonardo2718/lua-vermelha.svg?branch=devel)](https://travis-ci.org/Leonardo2718/lua-vermelha) 4 | 5 | Lua Vermelha is an implementation of [Lua](http://www.lua.org) 5.3 with a 6 | Just-In-Time (JIT) compiler built from 7 | [Eclipse OMR](https://github.com/eclipse/omr) compiler technology. 8 | 9 | It is designed to integrate into the [PUC-Rio Lua](http://www.lua.org) virtual 10 | machine with only minor modifications done to it. 11 | 12 | *(Please note that Lua Vermelha is under active development and may be unstable and definitely is buggy)* 13 | 14 | ## Cloning 15 | 16 | Lua Vermelha includes the Eclipse OMR project as a submodule so I recommend cloning 17 | this repo recursively: 18 | 19 | ```shell 20 | $ git clone --recursive https://github.com/Leonardo2718/lua-vermelha.git 21 | ``` 22 | 23 | ## Building 24 | 25 | Currently, the only tested and supported platform is Linux on x86-64. 26 | Support for other platforms will come later on. Until then, if you need to 27 | build Lua Vermelha on a different platform, you should be able to easily 28 | modify the makefiles manually to suit your needs. 29 | 30 | **IMPORTANT**: Before JitBuilder can be built (and by extension Lua Vermelha), 31 | it's important to configure OMR for your platform (see the 32 | [Eclipse OMR project page](https://github.com/eclipse/omr) for details): 33 | 34 | ```shell 35 | $ cd lua-vermelha/omr 36 | $ make -f run_configure.mk SPEC=linux_x86-64 OMRGLUE=./example/glue 37 | ``` 38 | 39 | The top level Makefile can then be used to build the Lua Vermelha executable 40 | interpreter frontend `luav`. 41 | 42 | ```shell 43 | $ cd .. # back to `lua-vermelha/` 44 | $ make -j4 # will recursively build JitBuilder, the JIT, the VM, and luav 45 | ``` 46 | 47 | ## Running 48 | 49 | The `luav` executable can be used the same way as the PUC-Rio Lua 50 | interpreter frontend (usually `lua`): 51 | 52 | ```shell 53 | $ luav # starts REPL 54 | $ luav file.lua # executes the Lua script `file.lua` 55 | $ luav luac.out # executes compiled Lua bytecode (output of `luac`) 56 | ``` 57 | 58 | ## Licensing 59 | 60 | Lua Vermelha has three components, each with their own licensing: 61 | 62 | * The (slightly) modified PUC-Rio Lua VM keeps its original license (MIT) 63 | and copy-right holders 64 | * The Lua Vermelha JIT compiler is distributed under two licenses: 65 | * [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html) 66 | * [Apache License v2.0](http://www.opensource.org/licenses/apache2.0.php) 67 | * The Eclipse OMR component is provided as a submodule pointing to the main 68 | project repository and is under the same licenses as the Lua Vermelha JIT 69 | -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha 2 | 3 | [![Build Status](https://travis-ci.org/Leonardo2718/lua-vermelha.svg?branch=devel)](https://travis-ci.org/Leonardo2718/lua-vermelha) 4 | 5 | Lua Vermelha是基于 [Eclipse OMR](https://github.com/eclipse/omr) JIT(Just-In-Time)编译器技术的一个 [Lua](http://www.lua.org) 5.3实现。 6 | 7 | Lua Vermelha的设计目标是:轻微修改 [PUC-Rio Lua](http://www.lua.org)虚拟机的代码,从而实现和Lua虚拟机的集成。 8 | 9 | *(注意:Lua Vermelha当前处于活跃的开发状态,可能还不太稳定还有bug)* 10 | 11 | ## 用git获取代码库 12 | 13 | Lua Vermelha把Eclipse OMR项目作为自己的一个子模块,所以推荐用 `--recursive` 参数来clone代码库。 14 | 15 | ```shell 16 | $ git clone --recursive https://github.com/Leonardo2718/lua-vermelha.git 17 | ``` 18 | 19 | ## 构建 20 | 21 | 当前唯一支持的平台是64位x86架构下的Linux。其他平台的支持敬请期待。如果你希望在其他平台下构建Lua Vermelha,只需要手工修改Makefile即可。 22 | 23 | **注意**:为了正确构建JitBuilder,配置好OMR是一件十分重要的事情(详细信息请参考[Eclipse OMR project page](https://github.com/eclipse/omr))。 24 | 25 | ```shell 26 | $ cd lua-vermelha/omr 27 | $ make -f run_configure.mk SPEC=linux_x86-64 OMRGLUE=./example/glue 28 | ``` 29 | 30 | 顶层目录里面的Makefile用来构建Lua Vermelha的执行前端程序 `luav` 。 31 | 32 | ```shell 33 | $ cd .. # 返回顶层目录 `lua-vermelha/` 34 | $ make -j4 # 依次构建 JitBuilder, the JIT, the VM, and luav 35 | ``` 36 | 37 | ## 运行 38 | 39 | 执行程序 `luav`的用法和 PUC-Rio Lua解释器(即 `lua`)的用法一样: 40 | 41 | ```shell 42 | $ luav # 启动交互式运行环境 43 | $ luav file.lua # 执行Lua脚本 `file.lua` 44 | $ luav luac.out # 执行Lua字节码 (由 `luac` 生成) 45 | ``` 46 | 47 | ## 许可 48 | 49 | Lua Vermelh有三个组件,各自使用各自的许可: 50 | 51 | * 微做修改的PUC-Rio Lua VM 仍使用其原始的许可(MIT许可) 52 | * Lua Vermelha JIT编译器用下列两种许可: 53 | * [Eclipse Public License 2](https://www.eclipse.org/legal/epl-2.0/) 54 | * [Apache License v2.0](http://www.opensource.org/licenses/apache2.0.php) 55 | * Eclipse OMR 组件的许可和 Lua Vermelha JIT一样 56 | -------------------------------------------------------------------------------- /doc/lua_vermelha.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha 2 | 3 | *Please note that Lua Vermelha is under active development and is not ready for a production environment.* 4 | 5 | ## Introduction 6 | 7 | Lua Vermelha is designed to behave the same way as PUC-Rio Lua. Any project 8 | that uses the PUC-Rio Lua as a library can also use Lua Vermelha. The main 9 | benefit it provides is improved performance, thanks to the JIT compiler, at 10 | the cost of a larger footprint. 11 | 12 | The JIT compiler is built using Eclipse OMR JitBuilder. JitBuilder is a 13 | framework that simplifies the creation of JIT compilers by leveraging 14 | the Eclipse OMR compiler technology. See the 15 | [Eclipse OMR GitHub page](https://github.com/eclipse/omr) for more details 16 | about the project. 17 | 18 | ## Architecture overview 19 | 20 | There are three main components that make up Lua Vermelha: 21 | 22 | 1. The minimally modified PUC-Rio Lua virtual machine 23 | 2. The Eclipse OMR JitBuilder library 24 | 3. The JIT compiler itself 25 | 26 | ### Lua VM 27 | 28 | The Lua VM provides the core functionality of the language implementation. 29 | It includes major components such as the interpreter and the garbage 30 | collector. The minimal changes done to it implement the necessary mechanism 31 | for dispatching the JIT compiler. 32 | 33 | When the Lua VM is instantiated, it initializes the JIT and starts the 34 | interpreter. When the interpreter encounters a function call, it dispatches 35 | the JIT, which will attempt to compile the function. If the compilation is 36 | successful, the interpreter calls the compiled function body. Subsequent 37 | calls to the function will also dispatch the JITed code. Otherwise, 38 | the function is simply interpreted and execution proceeds normally. 39 | 40 | This is by no means an optimal approach to JIT dispatching. However, it 41 | makes it easier to find and debug problems in the JIT. 42 | 43 | #### Lua patch file 44 | 45 | For convenience, this repo contains a git branch called `luavm` which contains 46 | the unchanged PUC-Rio Lua VM code. Each commit on this branch is tagged with 47 | the version of Lua it contains. 48 | 49 | The top-level Makefile on the `master` and `devel` branches has a special 50 | phony target called `lua-patch`. It can be used to generate a git patch file 51 | with the changes done applied to the VM between two commits. By default, 52 | it will use the current `HEAD` and `luavm` commits. Running 53 | 54 | ```sh 55 | $ make lua-patch 56 | ``` 57 | 58 | will generated a patch file called `luavm-HEAD.patch`. The `LUA` variable 59 | can be set to point to whatever commit contains the unchanged Lua code. 60 | Likewise, the `COMMIT` variable can be set to point to whatever commit 61 | contains the modified Lua VM code. 62 | 63 | ### Eclipse OMR JitBuilder 64 | 65 | The [Eclipse OMR Project](http://www.eclipse.org/omr) provides a collection 66 | of reusable cross-platform components for building language runtimes. One 67 | of these components is the compiler technology, which can be used to create 68 | JIT compilers. 69 | 70 | Although the compiler technology is very powerful and flexible, it is also 71 | very complex. The Eclipse OMR project therefore also provides a component 72 | called JitBuilder. 73 | 74 | JitBuilder is a framework that simplifies leveraging the Eclipse OMR 75 | compiler to build JITs. It reduces boiler plated code by provide sane 76 | default implementations for major tasks such as code optimization and 77 | code generation. It also provides a declarative interface for generating 78 | the Eclipse OMR Compiler intermediate language (IL). 79 | 80 | The JIT compiler in Lua Vermelha is built using JitBuilder. 81 | 82 | ### Lua Vermelha JIT 83 | 84 | The JIT compiler is the major components that makes Lua Vermelha what it is. 85 | 86 | When the JIT is invoked by the interpreter, it takes as parameter an 87 | object that contains the bytecode implementation of the function. It then 88 | iterates over each bytecode, generating IL that represents what the 89 | interpreter would do if it encountered the specific bytecode. If IL is 90 | successfully generated for each bytecode, the intermediate representation 91 | of the function is handed over to JitBuilder for optimization and 92 | code generation. 93 | 94 | If compilation is successful, JitBuilder will cache the compiled code 95 | in executable memory and return a pointer to it. The interpreter can 96 | then jump to the compiled body instead of interpreting the function. 97 | 98 | ## luav executable front end 99 | 100 | The top level `Makefile` can be used to create an executable Lua VM. It 101 | simply builds JitBuilder, builds the JIT (as a static library), builds 102 | the VM (also as a static library), builds the frontend, and links them 103 | all together. The VM and the frontend are built with `gcc` while JitBuilder 104 | and the JIT itself are compiled with `g++`. Linking is also done by `g++`. 105 | This Makefile serves as an example of how to build and consume Lua Vermelha. -------------------------------------------------------------------------------- /doc/lvjit_api.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha JIT API 2 | 3 | Lua Vermelha provides a special API that makes some JIT controls 4 | accessible to user code. This API has two components: the C API and 5 | the Lua library. Both offer the same functionality. 6 | 7 | ## JIT flags 8 | 9 | Lua Vermelha defines some "JIT flags" that can be used to "annotate" Lua 10 | functions. These flags modify how the VM controls the JIT with regards to 11 | the annotated functions. The following table describes the currently 12 | supported flags: 13 | 14 | | Flag Name | Description | 15 | |:-----------------|:-----------------------------------------| 16 | | `LUA_NOJITFLAGS` | No flags set (default) | 17 | | `LUA_BLACKLIST` | Prevent function from being JIT compiled | 18 | 19 | These flags are implemented as bit fields and can be combined using 20 | bit-wise operations. 21 | 22 | ## C API 23 | 24 | Lua Vermelha extends the standard Lua C API that provides some amount 25 | of the control of the JIT to user code. The following list describes 26 | each function provided by this API. 27 | 28 | ### `int lua_checkjitflags(lua_State* L, int index, int flags)` 29 | 30 | Checks if the given JIT flags are set on the function at the given stack 31 | index. The returned value is the result of masking the function's flags 32 | with the specified flags. In pseudo code `return function.flags & flags`. 33 | 34 | ### `void lua_setjitflags(lua_State* L, int index, int flags)` 35 | 36 | Sets the given flags on the function at the given stack index. Does not 37 | change the state (set or unset) of flags that are not specified. 38 | 39 | ### `void lua_clearjitflags(lua_State* L, int index, int flags)` 40 | 41 | Clears (unsets) the given flags on the function at the given stack index. 42 | Does not change the state (set or unset) of flags that are not specified. 43 | 44 | ### `int lua_initcallcounter(lua_State* L)` 45 | 46 | Returns the number of times a function must be called by the interpreter 47 | before it will attempt to JIT compile the function. 48 | 49 | ### `int lua_iscompiled(lua_State* L, int index)` 50 | 51 | Returns 1 if the function at the given stack index has been compiled (i.e. 52 | if a compiled body exists for it), 0 otherwise. 53 | 54 | ### `int lua_compile(lua_State* L, int index)` 55 | 56 | Will attempt to compile the function at the given stack index. Returns 1, 57 | if the compilation is successful, 0 otherwise. 58 | 59 | Note that this function ignores all JIT flags. That is, it will attempt 60 | to compile a function even if its `LUA_BLACKLIST` flag is set. 61 | 62 | ## Lua API 63 | 64 | The Lua API provides the same functionality as the C API. It is packaged 65 | in a library module called `lvjit`. The following table maps functions 66 | in the `lvjit` module to the corresponding C API functions. 67 | 68 | | lvjit | C API | 69 | |:------------------------|:----------------------| 70 | | `lvjit.checkjitflags` | `lua_checkjitflags` | 71 | | `lvjit.setjitflags` | `lua_setjitflags` | 72 | | `lvjit.clearjitflags` | `lua_clearjitflags` | 73 | | `lvjit.initcallcounter` | `lua_initcallcounter` | 74 | | `lvjit.iscompiled` | `lua_iscompiled` | 75 | | `lvjit.compile` | `lua_compile` | 76 | -------------------------------------------------------------------------------- /doc/zh/building.md: -------------------------------------------------------------------------------- 1 | # 构建和使用Lua Vermelha 2 | 3 | 每个组件的代码在不同的子目录里面: 4 | - `lua/` 修改后的 Lua VM 5 | - `omr/` Eclipse OMR and JitBuilder,以git 子模块的形式存在 6 | - `lvjit/` JIT 编译器 7 | 8 | Lua Vermelha的构建系统设计成可以支持不懂的使用方式。下面详细解说如何构建每个组件。 9 | 10 | *注意:当前Lua Vermelha仅仅在64位Linux下测试过,也只支持64位Linux。* 11 | 12 | ## JitBuilder 13 | 14 | JitBuilder是Eclipse OMR项目的一部分。当前仅支持作为静态库构建。在Lua Vermelha项目根目录运行下列脚本就可以构建JitBuilder。 15 | 16 | ```sh 17 | $ cd omr 18 | $ make -f run_configure.mk SPEC=linux_x86-64 OMRGLUE=./example/glue 19 | $ cd jitbuilder 20 | $ make -j4 PLATFORM=amd64-linux64-gcc 21 | ``` 22 | 23 | JitBuilder静态库构建后位于 `release/libjitbuilder.a`。 24 | 对应的C++ 头文件位于 `release/include/`。 25 | 26 | ## JIT 编译器 27 | 28 | JIT编译器可以灵活地构建成两种不同形式的二进制文件。 29 | 30 | 默认和推荐的JIT构建方式是构建成静态库(static library)。它就既能链接到VM库又能直接链接到应用程序执行文件里面。 31 | 32 | 当前支持的另一种方式是把JIT作为目标文件(object file)来链接。这种情况下,内部目标文件(intermediate object file,指每个c/c++文件生成的.o文件)被链接成一个单一的大的目标文件。这个单一目标文件可以被其他目标文件再次链接使用。 33 | 34 | 当前JIT必须直接链接到VM (不管使用什么二进制),所以构建成共享库当前还不被支持。 35 | 36 | 在JIT Makefile中提供了下列伪目标(phony target),以用来构建不同的二进制文件。 37 | 38 | * `staticlib` (`默认值`) 构建JIT成静态库 39 | * `lvjitobj` 构建JIT成目标文件 40 | 41 | 在构建JIT的时候,如果VM作为C代码来编译就必须定义宏 `LUA_C_LINKAGE` 。这可以保证当把JIT和VM链接在一起的时候,不会出现命名混乱问题。当调用 `make`的时候带上参数 `CXX_FLAGS_EXTRA='-DLUA_C_LINKAGE'` 就定义了 `LUA_C_LINKAGE` 宏(参考根目录下的Makefile)。 42 | 43 | 下列表格列出了在构建JIT的时候,`make` 的配置变量。 44 | 45 | | 变量 | 默认值 | 描述 | 46 | |:--------------------:|:-----------------:|:-----------------------| 47 | | `CXX` | `g++` | C++ 编译器 | 48 | | `AR` | `ar` | 静态库 .a 文件的创建器 | 49 | | `LD` | `ld` | 代码链接器 | 50 | | `CXX_FLAGS_EXTRA` | (empty) | 传递给C++编译器的额外参数 | 51 | | `LD_FLAGS_EXTRA` | (empty) | 传递给链接器的额外参数 | 52 | | `ARCH` | `x` (for x86) | CPU架构 | 53 | | `SUBARCH` | `amd64` | CPU子架构 | 54 | | `STATICLIB_NAME` | `liblvjit.a` | JIT静态库名 | 55 | | `LVJITOBJ_NAME` | `lvjit.o` | JIT目标文件名 | 56 | | `BIN_DIR` | `$(PWD)` | 编译后的二进制文件存放的目录 | 57 | | `STATICLIB_DEST` | `$(BIN_DIR)` | JIT静态库存放目录 | 58 | | `LVJITOBJ_DEST` | `$(BIN_DIR)` | JIT目标文件存放目录 | 59 | | `OBJS_DIR` | `$(BIN_DIR)/objs` | 编译生成的中间文件的存放目录 | 60 | | `LUA_DIR` | `../` | Lua VM代码目录 | 61 | | `OMR_DIR` | `../omr` | Eclipse OMR 代码目录 | 62 | | `JITBUILDER_LIB_DIR` | (见下表) | JitBuilder二进制文件目录 | 63 | 64 | 为了最大的灵活性,还提供了其他的变量,即使其他项目都不需要用到它们。 65 | 66 | | 变量 | 默认值 | 描述 | 67 | |:--------------------------:|:-------------------------------------:|:--------------| 68 | | `JITBUILDER_DIR` | `$(OMR_DIR)/jitbuilder` | JitBuilder代码目录 | 69 | | `JITBUILDER_ARCH_DIR` | `$(JITBUILDER_DIR)/$(ARCH)` | JitBuilder特定处理器代码目录 | 70 | | `JITBUILDER_SUBARCH_DIR` | `$(JITBUILDER_ARCH_DIR)/$(SUBARCH)` | JitBuilder特定处理器子架构代码目录 | 71 | | `JITBUILDER_LIB_DIR` | `$(JITBUILDER_DIR)/release` | (见上表) | 72 | | `JITBUILDER_HEADERS` | `$(JITBUILDER_LIB_DIR)/include` | JitBuilder 头文件目录 | 73 | | `OMR_COMPILER_DIR` | `$(OMR_DIR)/compiler` | Eclipse OMR 编译器代码目录 | 74 | | `OMR_COMPILER_ARCH_DIR` | `$(OMR_COMPILER_DIR)/$(ARCH)` | Eclipse OMR 编译器特定架构代码目录 | 75 | | `OMR_COMPILER_SUBARCH_DIR` | `$(OMR_COMPILER_ARCH_DIR)/$(SUBARCH)` | Eclipse OMR 编译器特定子架构代码目录 | 76 | 77 | ## Lua VM 78 | 79 | Lua VM的构建系统几乎没有修改过,应该和PUC-Rio Lua的构建方式一样。构建VM静态库可以使用下面的命令: 80 | 81 | ```sh 82 | $ cd lua 83 | $ make liblua.a SYSCFLAGS="-DLUA_USE_LINUX" 84 | ``` 85 | 86 | ## 把所有的组件组合在一起 87 | 88 | 一旦这三个组件分别构建成功,他们就可以链接成一个应用程序。重要提示:这个链接即可以由C++编译完成又可以通过显式链接C++标准库完成。 89 | 90 | 另外一种方式就是,把JIT和JitBuilder链接在一起(再强调一次,是用C++编译器链接),然后和C应用程序链接在一起。 91 | 92 | 示例链接命令如下(假设要链接 `lua.o`): 93 | 94 | ```sh 95 | $ g++ lua/lua.o lua/liblua.a lvjit/liblvjit.a omr/jitbuilder/release/libjitbuilder.a -ldl -lm -Wl,-E -lreadline 96 | ``` 97 | 98 | ## 完整的例子 99 | 100 | 下面两个例子都演示了如何构建 `luav`。注意:通过调用根目录下的makefile,同样可以得到例子中的构建结果。 101 | 102 | 把JIT作为静态库构建: 103 | 104 | ```sh 105 | $ lua 106 | $ make -j4 lua.o SYSCFLAGS="-DLUA_USE_LINUX" 107 | $ make -j4 liblua.a SYSCFLAGS="-DLUA_USE_LINUX" MYCFLAGS="-O2 -g" 108 | $ cd ../omr 109 | $ make -f run_configure.mk SPEC=linux_x86-64 OMRGLUE=./example/glue 110 | $ cd jitbuilder 111 | $ make -j4 CXX="g++" PLATFORM=amd64-linux64-gcc 112 | $ cd ../../lvjit 113 | $ make -j4 staticlib CXX="g++" CXX_FLAGS_EXTRA="-fpermissive -DLUA_C_LINKAGE -O3 -g" 114 | $ cd ../ 115 | $ g++ lua/lua.o lua/liblua.a lvjit/liblvjit.a omr/jitbuilder/release/libjitbuilder.a -ldl -lm -Wl,-E -lreadline 116 | ``` 117 | 118 | 另外一种方式,把JIT作为目标文件构建 119 | 120 | ```sh 121 | $ lua 122 | $ make -j4 lua.o SYSCFLAGS="-DLUA_USE_LINUX" 123 | $ make -j4 liblua.a SYSCFLAGS="-DLUA_USE_LINUX" MYCFLAGS="-O2 -g" 124 | $ cd ../omr 125 | $ make -f run_configure.mk SPEC=linux_x86-64 OMRGLUE=./example/glue 126 | $ cd jitbuilder 127 | $ make -j4 CXX="g++" PLATFORM=amd64-linux64-gcc 128 | $ cd ../../lvjit 129 | $ make -j4 lvjitobj CXX="g++" CXX_FLAGS_EXTRA="-fpermissive -DLUA_C_LINKAGE -O3 -g" 130 | $ cd ../ 131 | $ g++ lua/lua.o lua/liblua.a lvjit/lvjit.o omr/jitbuilder/release/libjitbuilder.a -ldl -lm -Wl,-E -lreadline 132 | ``` 133 | 134 | ## 根目录下的Makefile 135 | 136 | 根目录下的Makefile自动完成 `luav` 的构建过程,除了需要按上述方式配置OMR。配置OMR仍然需要用户手工完成。 137 | 138 | 构建过程可以通过下列变量来定制: 139 | 140 | | 变量 | 默认值 | 描述 | 141 | |:----------------:|:-----------------------:|:-----------------------| 142 | | `CC` | `gcc` | C编译器 | 143 | | `CXX` | `g++` | C++编译器 | 144 | | `BUILD_CONFIG` | `opt` | 值可以是 `debug`, `opt`, 和 `prod` 之一| 145 | | `LUAV` | `luav` | 最终应用程序名 | 146 | | `LUA_APP` | `lua.o` | 应用程序目标文件名 | 147 | | `LUA_LIB` | `liblua.a` | Lua VM静态库文件名 | 148 | | `LVJIT_LIB` | `liblvjit.a` | Lua Vermelha JIT静态库文件名 | 149 | | `JITBUILDER_LIB` | `libjitbuilder.a` | JitBuilder静态库文件名 | 150 | | `LUA_DIR` | `$(PWD)/lua` | Lua VM 代码目录 | 151 | | `LVJIT_DIR` | `$(PWD)/lvjit` | JIT代码目录 | 152 | | `JITBUILDER_DIR` | `$(PWD)/omr/jitbuilder` | JitBuilder代码目录 | 153 | 154 | `BUILD_CONFIG` 的值指定了构建结构的类型: 155 | 156 | * `debug` 构建结果带调试符号,代码没有优化 157 | * `opt` 构建结果带调试符号,但是代码被优化 158 | * `prod` 构建结果不带调试符合,并且代码被优化 159 | 160 | 下面的命令将会使用JIT的静态库来构建 `luav`: 161 | 162 | ```sh 163 | $ make -j4 164 | ``` 165 | 166 | 下面的命令将会构建一个调试版本的 `luav`,同时使用的是JIT的目标文件。 167 | ```sh 168 | $ make -j4 LVJIT_LIB=lvjit.o BUILD_CONFIG=debug 169 | ``` 170 | -------------------------------------------------------------------------------- /doc/zh/lua_vermelha.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha 2 | 3 | *请注意:Lua Vermelha当前处于活跃的开发状态,还不适用于生产环境。* 4 | 5 | ## 简介 6 | 7 | Lua Vermelha被设计成与PUC-Rio Lua有相同的运行表现。任何使用PUC-Rio Lua作为库的项目也可以使用 8 | Lua Vermelha。归功于JIT编译器,在使用了JIT编译器后能提供更好的性能,但是也付出了文件体积更大的代价。 9 | 10 | JIT编译器使用Eclipse OMR JitBuilder来构建。 JitBuilder是一个基于Eclipse OMR编译器技术用来简化创建JIT编译器的框架。 11 | 更多Eclipse OMR信息请参考[Eclipse OMR GitHub 主页](https://github.com/eclipse/omr)。 12 | 13 | ## 架构概述 14 | 15 | Lua Vermelha主要由下面三个组件构成: 16 | 17 | 1. 轻微修改过的PUC-Rio Lua 虚拟机 18 | 2. Eclipse OMR JitBuilder 库 19 | 3. JIT编译器 20 | 21 | ### Lua虚拟机 22 | 23 | Lua虚拟机提供了Lua语言核心功能的实现。它主要包括解释器和垃圾回收器。轻微修改后的代码实现了分发调用给JIT编译器的必要机制。 24 | 25 | 当Lua虚拟机实例化后,它初始化JIT编译器并开始运行解释器。当解释器遇到函数调用的时候,它就分发调用给JIT,JIT就尝试去编译该函数。 26 | 如果编译成功,解释器就调用编译后的函数代码。随后的函数调用也会被分发给JIT。如果编译失败,该函数依旧按Lua虚拟机原有的方式解释执行。 27 | 28 | 这里没有使用任何方式来优化JIT的调用分发。但是这种方式能更容易发现和调试JIT本身的问题。 29 | 30 | #### Lua patch 文件 31 | 32 | 为了方便起见,代码库里面有个git分支 `luavm` 用来存放更改之前的PUC-Rio Lua虚拟机代码。这个分支上每次提交都标记了其对应的Lua版本。 33 | 34 | 分支 `master`和`devel`的根目录Makefile里面有一个特殊的伪目标(phony target) `lua-patch`。它可以用来生成git patch文件,该patch文件含有两次提交之间Lua虚拟机代码的改动。默认情况下,这两次提交是当前的 `HEAD` 和 `luavm`。 35 | 36 | 运行下面的命令 37 | 38 | ```sh 39 | $ make lua-patch 40 | ``` 41 | 将会生成名为 `luavm-HEAD.patch` patch文件。`LUA` 变量可以用来指向没有改动过的Lua代码的提交。 42 | 类似地,`COMMIT` 变量用来指向改动了的Lua代码的提交。 43 | 44 | ### Eclipse OMR JitBuilder 45 | 46 | [Eclipse OMR 项目](http://www.eclipse.org/omr) 提供了一组用于构建语言运行时的可重用跨平台的组件。 47 | 其中一个组件就是编译器技术,它可以用来创建JIT编译器。 48 | 49 | 尽管OMR编译器技术非常得强大和灵活,但是它也十分复杂。因此Eclipse OMR项目又提供了一个名叫JitBuilder的组件。 50 | 51 | JitBuilder是一个利用Eclipse OMR编译器来简化构建JIT的框架。它通过提供诸如代码优化和代码生成这些主要任务的默认实现从而减少了对样本代码的编写工作量。它也提供了生成Eclipse OMR编译器中间语言(IL)的声明接口。 52 | 53 | 在Lua Vermelha中,JIT编译器使用JitBuilder构建。 54 | 55 | ### Lua Vermelha JIT 56 | 57 | JIT编译器是使Lua Vermelha成为当前样子的主要组件。 58 | 59 | 当JIT被解释器调用的时候,它获得一个参数,该参数是一个函数字节码实现的对象。然后它开始遍历字节码, 60 | 生成IL,这些IL模拟了解释器遇到这些字节码的时候的处理行为。如果每个字节码都成功地生成了IL,那么这些 61 | 函数的中间格式就传递给JitBuilder以用于代码优化和生成。 62 | 63 | 如果编译成功,JitBuilder将会在内存里面缓存编译后的代码并返回一个指向它的指针。解释器就能替换掉解释代码从而跳转到编译后代码处。 64 | 65 | ## luav 执行程序前端 66 | 67 | 根目录下的 `Makefile` 可以用来生成可以运行的Lua VM。它简单地构建JitBuilder、JIT(静态库)、VM(静态库)和前端,然后把这些链接起来。VM和前端代码使用 `gcc` 编译,而JitBuilder和JIT使用 `g++` 编译。链接工具也使用 `g++`。这个Makefile可以作为一个例子来演示如何构建和使用Lua Vermelha。 -------------------------------------------------------------------------------- /doc/zh/lvjit_api.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha JIT API 2 | 3 | Lua Vermelha 提供了一个特有的API使得用户代码可以容易地控制JIT。API有两个组件:C语言API和Lua库。 4 | 这两者都提供了相同的功能。 5 | 6 | ## JIT 标志 7 | 8 | Lua Vermelha 定义了一些 “JIT标志”,可以用来标注Lua函数。这些标志能修改VM如何控制JIT来处理标注函数的方式。下表说明了当前支持的标志: 9 | 10 | | 标志名称 | 说明 | 11 | |:-----------------|:-----------------------------------------| 12 | | `LUA_NOJITFLAGS` | 没有标志 (默认值) | 13 | | `LUA_BLACKLIST` | 不允许函数被JIT编译 | 14 | 15 | 这些标志用bit字段实现,可以用bit操作符来组合使用。 16 | 17 | ## C语言 API 18 | 19 | Lua Vermelha 扩展了标准的Lua C语言API,为用户代码提供了很多控制JIT的方法。 20 | 下面详细说明API提供的每个函数。 21 | 22 | ### `int lua_checkjitflags(lua_State* L, int index, int flags)` 23 | 24 | 检查指定栈上的函数是否设置了JIT标志。返回结果是函数标志和参数标志的掩码。 25 | 伪代码就是:`return function.flags & flags`。 26 | 27 | ### `void lua_setjitflags(lua_State* L, int index, int flags)` 28 | 29 | 给指定栈上的函数设置JIT标志。其他的没有指定的标志不改变原有的状态。 30 | 31 | ### `void lua_clearjitflags(lua_State* L, int index, int flags)` 32 | 33 | 清除指定栈上的指定JIT标志。其他的没有指定的标志不会改变原有的状态。 34 | 35 | ### `int lua_initcallcounter(lua_State* L)` 36 | 37 | 返回函数在被解释器试图调用JIT编译之前需要被调用的次数。 38 | 39 | ### `int lua_iscompiled(lua_State* L, int index)` 40 | 41 | 如果指定栈上的代码被编译过(例如:存在被编译过的代码)就返回 1 ,否则返回 0 。 42 | 43 | ### `int lua_compile(lua_State* L, int index)` 44 | 45 | 开始编译指定栈上的函数代码。编译成功返回 1 , 否则返回 0 。 46 | 47 | 注意:这个函数忽略所有的JIT标志。也就是说,即使 设置了`LUA_BLACKLIST`,它仍然会编译该函数。 48 | 49 | ## Lua API 50 | 51 | Lua API提供了和C语言API一样的功能。它打包成一个名叫 `lvjit` 的库里面。 52 | 下表说明了 `lvjit` 模块里面各个函数和C语言API函数的对应关系。 53 | 54 | | lvjit | C API | 55 | |:------------------------|:----------------------| 56 | | `lvjit.checkjitflags` | `lua_checkjitflags` | 57 | | `lvjit.setjitflags` | `lua_setjitflags` | 58 | | `lvjit.clearjitflags` | `lua_clearjitflags` | 59 | | `lvjit.initcallcounter` | `lua_initcallcounter` | 60 | | `lvjit.iscompiled` | `lua_iscompiled` | 61 | | `lvjit.compile` | `lua_compile` | 62 | -------------------------------------------------------------------------------- /lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /lua/lbitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp $ 3 | ** Standard library for bitwise operations 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lbitlib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #if defined(LUA_COMPAT_BITLIB) /* { */ 20 | 21 | 22 | #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) 23 | #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i)) 24 | 25 | 26 | /* number of bits to consider in a number */ 27 | #if !defined(LUA_NBITS) 28 | #define LUA_NBITS 32 29 | #endif 30 | 31 | 32 | /* 33 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must 34 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the 35 | ** number of bits in a lua_Unsigned.) 36 | */ 37 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) 38 | 39 | 40 | /* macro to trim extra bits */ 41 | #define trim(x) ((x) & ALLONES) 42 | 43 | 44 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 45 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) 46 | 47 | 48 | 49 | static lua_Unsigned andaux (lua_State *L) { 50 | int i, n = lua_gettop(L); 51 | lua_Unsigned r = ~(lua_Unsigned)0; 52 | for (i = 1; i <= n; i++) 53 | r &= checkunsigned(L, i); 54 | return trim(r); 55 | } 56 | 57 | 58 | static int b_and (lua_State *L) { 59 | lua_Unsigned r = andaux(L); 60 | pushunsigned(L, r); 61 | return 1; 62 | } 63 | 64 | 65 | static int b_test (lua_State *L) { 66 | lua_Unsigned r = andaux(L); 67 | lua_pushboolean(L, r != 0); 68 | return 1; 69 | } 70 | 71 | 72 | static int b_or (lua_State *L) { 73 | int i, n = lua_gettop(L); 74 | lua_Unsigned r = 0; 75 | for (i = 1; i <= n; i++) 76 | r |= checkunsigned(L, i); 77 | pushunsigned(L, trim(r)); 78 | return 1; 79 | } 80 | 81 | 82 | static int b_xor (lua_State *L) { 83 | int i, n = lua_gettop(L); 84 | lua_Unsigned r = 0; 85 | for (i = 1; i <= n; i++) 86 | r ^= checkunsigned(L, i); 87 | pushunsigned(L, trim(r)); 88 | return 1; 89 | } 90 | 91 | 92 | static int b_not (lua_State *L) { 93 | lua_Unsigned r = ~checkunsigned(L, 1); 94 | pushunsigned(L, trim(r)); 95 | return 1; 96 | } 97 | 98 | 99 | static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { 100 | if (i < 0) { /* shift right? */ 101 | i = -i; 102 | r = trim(r); 103 | if (i >= LUA_NBITS) r = 0; 104 | else r >>= i; 105 | } 106 | else { /* shift left */ 107 | if (i >= LUA_NBITS) r = 0; 108 | else r <<= i; 109 | r = trim(r); 110 | } 111 | pushunsigned(L, r); 112 | return 1; 113 | } 114 | 115 | 116 | static int b_lshift (lua_State *L) { 117 | return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); 118 | } 119 | 120 | 121 | static int b_rshift (lua_State *L) { 122 | return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); 123 | } 124 | 125 | 126 | static int b_arshift (lua_State *L) { 127 | lua_Unsigned r = checkunsigned(L, 1); 128 | lua_Integer i = luaL_checkinteger(L, 2); 129 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) 130 | return b_shift(L, r, -i); 131 | else { /* arithmetic shift for 'negative' number */ 132 | if (i >= LUA_NBITS) r = ALLONES; 133 | else 134 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ 135 | pushunsigned(L, r); 136 | return 1; 137 | } 138 | } 139 | 140 | 141 | static int b_rot (lua_State *L, lua_Integer d) { 142 | lua_Unsigned r = checkunsigned(L, 1); 143 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ 144 | r = trim(r); 145 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ 146 | r = (r << i) | (r >> (LUA_NBITS - i)); 147 | pushunsigned(L, trim(r)); 148 | return 1; 149 | } 150 | 151 | 152 | static int b_lrot (lua_State *L) { 153 | return b_rot(L, luaL_checkinteger(L, 2)); 154 | } 155 | 156 | 157 | static int b_rrot (lua_State *L) { 158 | return b_rot(L, -luaL_checkinteger(L, 2)); 159 | } 160 | 161 | 162 | /* 163 | ** get field and width arguments for field-manipulation functions, 164 | ** checking whether they are valid. 165 | ** ('luaL_error' called without 'return' to avoid later warnings about 166 | ** 'width' being used uninitialized.) 167 | */ 168 | static int fieldargs (lua_State *L, int farg, int *width) { 169 | lua_Integer f = luaL_checkinteger(L, farg); 170 | lua_Integer w = luaL_optinteger(L, farg + 1, 1); 171 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); 172 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); 173 | if (f + w > LUA_NBITS) 174 | luaL_error(L, "trying to access non-existent bits"); 175 | *width = (int)w; 176 | return (int)f; 177 | } 178 | 179 | 180 | static int b_extract (lua_State *L) { 181 | int w; 182 | lua_Unsigned r = trim(checkunsigned(L, 1)); 183 | int f = fieldargs(L, 2, &w); 184 | r = (r >> f) & mask(w); 185 | pushunsigned(L, r); 186 | return 1; 187 | } 188 | 189 | 190 | static int b_replace (lua_State *L) { 191 | int w; 192 | lua_Unsigned r = trim(checkunsigned(L, 1)); 193 | lua_Unsigned v = trim(checkunsigned(L, 2)); 194 | int f = fieldargs(L, 3, &w); 195 | lua_Unsigned m = mask(w); 196 | r = (r & ~(m << f)) | ((v & m) << f); 197 | pushunsigned(L, r); 198 | return 1; 199 | } 200 | 201 | 202 | static const luaL_Reg bitlib[] = { 203 | {"arshift", b_arshift}, 204 | {"band", b_and}, 205 | {"bnot", b_not}, 206 | {"bor", b_or}, 207 | {"bxor", b_xor}, 208 | {"btest", b_test}, 209 | {"extract", b_extract}, 210 | {"lrotate", b_lrot}, 211 | {"lshift", b_lshift}, 212 | {"replace", b_replace}, 213 | {"rrotate", b_rrot}, 214 | {"rshift", b_rshift}, 215 | {NULL, NULL} 216 | }; 217 | 218 | 219 | 220 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 221 | luaL_newlib(L, bitlib); 222 | return 1; 223 | } 224 | 225 | 226 | #else /* }{ */ 227 | 228 | 229 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 230 | return luaL_error(L, "library 'bit32' has been deprecated"); 231 | } 232 | 233 | #endif /* } */ 234 | -------------------------------------------------------------------------------- /lua/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 28 | OPR_DIV, 29 | OPR_IDIV, 30 | OPR_BAND, OPR_BOR, OPR_BXOR, 31 | OPR_SHL, OPR_SHR, 32 | OPR_CONCAT, 33 | OPR_EQ, OPR_LT, OPR_LE, 34 | OPR_NE, OPR_GT, OPR_GE, 35 | OPR_AND, OPR_OR, 36 | OPR_NOBINOPR 37 | } BinOpr; 38 | 39 | 40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 41 | 42 | 43 | /* get (pointer to) instruction of given 'expdesc' */ 44 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) 45 | 46 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 47 | 48 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 49 | 50 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 51 | 52 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 53 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 54 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); 55 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 56 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 57 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 58 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 59 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 60 | LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n); 61 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 62 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 63 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 64 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 65 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 66 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 67 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 68 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 69 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 70 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 71 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 72 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 73 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 74 | LUAI_FUNC int luaK_jump (FuncState *fs); 75 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 76 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 77 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 78 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); 79 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 80 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 81 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 82 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 83 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 84 | expdesc *v2, int line); 85 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /lua/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argcheck(L, co, 1, "thread expected"); 24 | return co; 25 | } 26 | 27 | 28 | static int auxresume (lua_State *L, lua_State *co, int narg) { 29 | int status; 30 | if (!lua_checkstack(co, narg)) { 31 | lua_pushliteral(L, "too many arguments to resume"); 32 | return -1; /* error flag */ 33 | } 34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 35 | lua_pushliteral(L, "cannot resume dead coroutine"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg); 40 | if (status == LUA_OK || status == LUA_YIELD) { 41 | int nres = lua_gettop(co); 42 | if (!lua_checkstack(L, nres + 1)) { 43 | lua_pop(co, nres); /* remove results anyway */ 44 | lua_pushliteral(L, "too many results to resume"); 45 | return -1; /* error flag */ 46 | } 47 | lua_xmove(co, L, nres); /* move yielded values */ 48 | return nres; 49 | } 50 | else { 51 | lua_xmove(co, L, 1); /* move error message */ 52 | return -1; /* error flag */ 53 | } 54 | } 55 | 56 | 57 | static int luaB_coresume (lua_State *L) { 58 | lua_State *co = getco(L); 59 | int r; 60 | r = auxresume(L, co, lua_gettop(L) - 1); 61 | if (r < 0) { 62 | lua_pushboolean(L, 0); 63 | lua_insert(L, -2); 64 | return 2; /* return false + error message */ 65 | } 66 | else { 67 | lua_pushboolean(L, 1); 68 | lua_insert(L, -(r + 1)); 69 | return r + 1; /* return true + 'resume' returns */ 70 | } 71 | } 72 | 73 | 74 | static int luaB_auxwrap (lua_State *L) { 75 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 76 | int r = auxresume(L, co, lua_gettop(L)); 77 | if (r < 0) { 78 | if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ 79 | luaL_where(L, 1); /* add extra info */ 80 | lua_insert(L, -2); 81 | lua_concat(L, 2); 82 | } 83 | return lua_error(L); /* propagate error */ 84 | } 85 | return r; 86 | } 87 | 88 | 89 | static int luaB_cocreate (lua_State *L) { 90 | lua_State *NL; 91 | luaL_checktype(L, 1, LUA_TFUNCTION); 92 | NL = lua_newthread(L); 93 | lua_pushvalue(L, 1); /* move function to top */ 94 | lua_xmove(L, NL, 1); /* move function from L to NL */ 95 | return 1; 96 | } 97 | 98 | 99 | static int luaB_cowrap (lua_State *L) { 100 | luaB_cocreate(L); 101 | lua_pushcclosure(L, luaB_auxwrap, 1); 102 | return 1; 103 | } 104 | 105 | 106 | static int luaB_yield (lua_State *L) { 107 | return lua_yield(L, lua_gettop(L)); 108 | } 109 | 110 | 111 | static int luaB_costatus (lua_State *L) { 112 | lua_State *co = getco(L); 113 | if (L == co) lua_pushliteral(L, "running"); 114 | else { 115 | switch (lua_status(co)) { 116 | case LUA_YIELD: 117 | lua_pushliteral(L, "suspended"); 118 | break; 119 | case LUA_OK: { 120 | lua_Debug ar; 121 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 122 | lua_pushliteral(L, "normal"); /* it is running */ 123 | else if (lua_gettop(co) == 0) 124 | lua_pushliteral(L, "dead"); 125 | else 126 | lua_pushliteral(L, "suspended"); /* initial state */ 127 | break; 128 | } 129 | default: /* some error occurred */ 130 | lua_pushliteral(L, "dead"); 131 | break; 132 | } 133 | } 134 | return 1; 135 | } 136 | 137 | 138 | static int luaB_yieldable (lua_State *L) { 139 | lua_pushboolean(L, lua_isyieldable(L)); 140 | return 1; 141 | } 142 | 143 | 144 | static int luaB_corunning (lua_State *L) { 145 | int ismain = lua_pushthread(L); 146 | lua_pushboolean(L, ismain); 147 | return 2; 148 | } 149 | 150 | 151 | static const luaL_Reg co_funcs[] = { 152 | {"create", luaB_cocreate}, 153 | {"resume", luaB_coresume}, 154 | {"running", luaB_corunning}, 155 | {"status", luaB_costatus}, 156 | {"wrap", luaB_cowrap}, 157 | {"yield", luaB_yield}, 158 | {"isyieldable", luaB_yieldable}, 159 | {NULL, NULL} 160 | }; 161 | 162 | 163 | 164 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 165 | luaL_newlib(L, co_funcs); 166 | return 1; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /lua/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 20 | 0x00, /* EOZ */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | }; 54 | 55 | #endif /* } */ 56 | -------------------------------------------------------------------------------- /lua/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 15 | 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 24 | const TValue *p2); 25 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 26 | const TValue *p2, 27 | const char *msg); 28 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 29 | const TValue *p2); 30 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 31 | const TValue *p2); 32 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 33 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 34 | TString *src, int line); 35 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 36 | LUAI_FUNC void luaG_traceexec (lua_State *L); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /lua/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 21 | ** at every check. 22 | */ 23 | #define luaD_checkstackaux(L,n,pre,pos) \ 24 | if (L->stack_last - L->top <= (n)) \ 25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } 26 | 27 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 29 | 30 | 31 | 32 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 33 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 34 | 35 | 36 | /* type of protected functions, to be ran by 'runprotected' */ 37 | typedef void (*Pfunc) (lua_State *L, void *ud); 38 | 39 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 40 | const char *mode); 41 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 46 | ptrdiff_t oldtop, ptrdiff_t ef); 47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, 48 | int nres); 49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 52 | LUAI_FUNC void luaD_inctop (lua_State *L); 53 | 54 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 55 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /lua/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lobject.h" 18 | #include "lstate.h" 19 | #include "lundump.h" 20 | 21 | 22 | typedef struct { 23 | lua_State *L; 24 | lua_Writer writer; 25 | void *data; 26 | int strip; 27 | int status; 28 | } DumpState; 29 | 30 | 31 | /* 32 | ** All high-level dumps go through DumpVector; you can change it to 33 | ** change the endianness of the result 34 | */ 35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) 36 | 37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) 38 | 39 | 40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { 41 | if (D->status == 0 && size > 0) { 42 | lua_unlock(D->L); 43 | D->status = (*D->writer)(D->L, b, size, D->data); 44 | lua_lock(D->L); 45 | } 46 | } 47 | 48 | 49 | #define DumpVar(x,D) DumpVector(&x,1,D) 50 | 51 | 52 | static void DumpByte (int y, DumpState *D) { 53 | lu_byte x = (lu_byte)y; 54 | DumpVar(x, D); 55 | } 56 | 57 | 58 | static void DumpInt (int x, DumpState *D) { 59 | DumpVar(x, D); 60 | } 61 | 62 | 63 | static void DumpNumber (lua_Number x, DumpState *D) { 64 | DumpVar(x, D); 65 | } 66 | 67 | 68 | static void DumpInteger (lua_Integer x, DumpState *D) { 69 | DumpVar(x, D); 70 | } 71 | 72 | 73 | static void DumpString (const TString *s, DumpState *D) { 74 | if (s == NULL) 75 | DumpByte(0, D); 76 | else { 77 | size_t size = tsslen(s) + 1; /* include trailing '\0' */ 78 | const char *str = getstr(s); 79 | if (size < 0xFF) 80 | DumpByte(cast_int(size), D); 81 | else { 82 | DumpByte(0xFF, D); 83 | DumpVar(size, D); 84 | } 85 | DumpVector(str, size - 1, D); /* no need to save '\0' */ 86 | } 87 | } 88 | 89 | 90 | static void DumpCode (const Proto *f, DumpState *D) { 91 | DumpInt(f->sizecode, D); 92 | DumpVector(f->code, f->sizecode, D); 93 | } 94 | 95 | 96 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); 97 | 98 | static void DumpConstants (const Proto *f, DumpState *D) { 99 | int i; 100 | int n = f->sizek; 101 | DumpInt(n, D); 102 | for (i = 0; i < n; i++) { 103 | const TValue *o = &f->k[i]; 104 | DumpByte(ttype(o), D); 105 | switch (ttype(o)) { 106 | case LUA_TNIL: 107 | break; 108 | case LUA_TBOOLEAN: 109 | DumpByte(bvalue(o), D); 110 | break; 111 | case LUA_TNUMFLT: 112 | DumpNumber(fltvalue(o), D); 113 | break; 114 | case LUA_TNUMINT: 115 | DumpInteger(ivalue(o), D); 116 | break; 117 | case LUA_TSHRSTR: 118 | case LUA_TLNGSTR: 119 | DumpString(tsvalue(o), D); 120 | break; 121 | default: 122 | lua_assert(0); 123 | } 124 | } 125 | } 126 | 127 | 128 | static void DumpProtos (const Proto *f, DumpState *D) { 129 | int i; 130 | int n = f->sizep; 131 | DumpInt(n, D); 132 | for (i = 0; i < n; i++) 133 | DumpFunction(f->p[i], f->source, D); 134 | } 135 | 136 | 137 | static void DumpUpvalues (const Proto *f, DumpState *D) { 138 | int i, n = f->sizeupvalues; 139 | DumpInt(n, D); 140 | for (i = 0; i < n; i++) { 141 | DumpByte(f->upvalues[i].instack, D); 142 | DumpByte(f->upvalues[i].idx, D); 143 | } 144 | } 145 | 146 | 147 | static void DumpDebug (const Proto *f, DumpState *D) { 148 | int i, n; 149 | n = (D->strip) ? 0 : f->sizelineinfo; 150 | DumpInt(n, D); 151 | DumpVector(f->lineinfo, n, D); 152 | n = (D->strip) ? 0 : f->sizelocvars; 153 | DumpInt(n, D); 154 | for (i = 0; i < n; i++) { 155 | DumpString(f->locvars[i].varname, D); 156 | DumpInt(f->locvars[i].startpc, D); 157 | DumpInt(f->locvars[i].endpc, D); 158 | } 159 | n = (D->strip) ? 0 : f->sizeupvalues; 160 | DumpInt(n, D); 161 | for (i = 0; i < n; i++) 162 | DumpString(f->upvalues[i].name, D); 163 | } 164 | 165 | 166 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { 167 | if (D->strip || f->source == psource) 168 | DumpString(NULL, D); /* no debug info or same source as its parent */ 169 | else 170 | DumpString(f->source, D); 171 | DumpInt(f->linedefined, D); 172 | DumpInt(f->lastlinedefined, D); 173 | DumpByte(f->numparams, D); 174 | DumpByte(f->is_vararg, D); 175 | DumpByte(f->maxstacksize, D); 176 | DumpCode(f, D); 177 | DumpConstants(f, D); 178 | DumpUpvalues(f, D); 179 | DumpProtos(f, D); 180 | DumpDebug(f, D); 181 | } 182 | 183 | 184 | static void DumpHeader (DumpState *D) { 185 | DumpLiteral(LUA_SIGNATURE, D); 186 | DumpByte(LUAC_VERSION, D); 187 | DumpByte(LUAC_FORMAT, D); 188 | DumpLiteral(LUAC_DATA, D); 189 | DumpByte(sizeof(int), D); 190 | DumpByte(sizeof(size_t), D); 191 | DumpByte(sizeof(Instruction), D); 192 | DumpByte(sizeof(lua_Integer), D); 193 | DumpByte(sizeof(lua_Number), D); 194 | DumpInteger(LUAC_INT, D); 195 | DumpNumber(LUAC_NUM, D); 196 | } 197 | 198 | 199 | /* 200 | ** dump Lua function as precompiled chunk 201 | */ 202 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 203 | int strip) { 204 | DumpState D; 205 | D.L = L; 206 | D.writer = w; 207 | D.data = data; 208 | D.strip = strip; 209 | D.status = 0; 210 | DumpHeader(&D); 211 | DumpByte(f->sizeupvalues, &D); 212 | DumpFunction(f, NULL, &D); 213 | return D.status; 214 | } 215 | 216 | -------------------------------------------------------------------------------- /lua/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lfunc_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | #include "luav.h" 17 | 18 | #include "lfunc.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | #include "lvjit.h" 24 | 25 | 26 | 27 | CClosure *luaF_newCclosure (lua_State *L, int n) { 28 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); 29 | CClosure *c = gco2ccl(o); 30 | c->nupvalues = cast_byte(n); 31 | return c; 32 | } 33 | 34 | 35 | LClosure *luaF_newLclosure (lua_State *L, int n) { 36 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); 37 | LClosure *c = gco2lcl(o); 38 | c->p = NULL; 39 | c->nupvalues = cast_byte(n); 40 | while (n--) c->upvals[n] = NULL; 41 | return c; 42 | } 43 | 44 | /* 45 | ** fill a closure with new closed upvalues 46 | */ 47 | void luaF_initupvals (lua_State *L, LClosure *cl) { 48 | int i; 49 | for (i = 0; i < cl->nupvalues; i++) { 50 | UpVal *uv = luaM_new(L, UpVal); 51 | uv->refcount = 1; 52 | uv->v = &uv->u.value; /* make it closed */ 53 | setnilvalue(uv->v); 54 | cl->upvals[i] = uv; 55 | } 56 | } 57 | 58 | 59 | UpVal *luaF_findupval (lua_State *L, StkId level) { 60 | UpVal **pp = &L->openupval; 61 | UpVal *p; 62 | UpVal *uv; 63 | lua_assert(isintwups(L) || L->openupval == NULL); 64 | while (*pp != NULL && (p = *pp)->v >= level) { 65 | lua_assert(upisopen(p)); 66 | if (p->v == level) /* found a corresponding upvalue? */ 67 | return p; /* return it */ 68 | pp = &p->u.open.next; 69 | } 70 | /* not found: create a new upvalue */ 71 | uv = luaM_new(L, UpVal); 72 | uv->refcount = 0; 73 | uv->u.open.next = *pp; /* link it to list of open upvalues */ 74 | uv->u.open.touched = 1; 75 | *pp = uv; 76 | uv->v = level; /* current value lives in the stack */ 77 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 78 | L->twups = G(L)->twups; /* link it to the list */ 79 | G(L)->twups = L; 80 | } 81 | return uv; 82 | } 83 | 84 | 85 | void luaF_close (lua_State *L, StkId level) { 86 | UpVal *uv; 87 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { 88 | lua_assert(upisopen(uv)); 89 | L->openupval = uv->u.open.next; /* remove from 'open' list */ 90 | if (uv->refcount == 0) /* no references? */ 91 | luaM_free(L, uv); /* free upvalue */ 92 | else { 93 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 94 | uv->v = &uv->u.value; /* now current value lives here */ 95 | luaC_upvalbarrier(L, uv); 96 | } 97 | } 98 | } 99 | 100 | 101 | Proto *luaF_newproto (lua_State *L) { 102 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); 103 | Proto *f = gco2p(o); 104 | f->k = NULL; 105 | f->sizek = 0; 106 | f->p = NULL; 107 | f->sizep = 0; 108 | f->code = NULL; 109 | f->compiledcode = NULL; 110 | f->jitflags = LUA_NOJITFLAGS; 111 | f->callcounter = luaJ_initcallcounter(); 112 | f->cache = NULL; 113 | f->sizecode = 0; 114 | f->lineinfo = NULL; 115 | f->sizelineinfo = 0; 116 | f->upvalues = NULL; 117 | f->sizeupvalues = 0; 118 | f->numparams = 0; 119 | f->is_vararg = 0; 120 | f->maxstacksize = 0; 121 | f->locvars = NULL; 122 | f->sizelocvars = 0; 123 | f->linedefined = 0; 124 | f->lastlinedefined = 0; 125 | f->source = NULL; 126 | return f; 127 | } 128 | 129 | 130 | void luaF_freeproto (lua_State *L, Proto *f) { 131 | luaM_freearray(L, f->code, f->sizecode); 132 | luaM_freearray(L, f->p, f->sizep); 133 | luaM_freearray(L, f->k, f->sizek); 134 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 135 | luaM_freearray(L, f->locvars, f->sizelocvars); 136 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 137 | luaM_free(L, f); 138 | } 139 | 140 | 141 | /* 142 | ** Look for n-th local variable at line 'line' in function 'func'. 143 | ** Returns NULL if not found. 144 | */ 145 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 146 | int i; 147 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 148 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 149 | local_number--; 150 | if (local_number == 0) 151 | return getstr(f->locvars[i].varname); 152 | } 153 | } 154 | return NULL; /* not found */ 155 | } 156 | 157 | -------------------------------------------------------------------------------- /lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | /* 33 | ** Upvalues for Lua closures 34 | */ 35 | struct UpVal { 36 | TValue *v; /* points to stack or to its own value */ 37 | lu_mem refcount; /* reference counter */ 38 | union { 39 | struct { /* (when open) */ 40 | UpVal *next; /* linked list */ 41 | int touched; /* mark to avoid cycles with dead threads */ 42 | } open; 43 | TValue value; /* the value (when closed) */ 44 | } u; 45 | }; 46 | 47 | #define upisopen(up) ((up)->v != &(up)->u.value) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 57 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 58 | int pc); 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /lua/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | 29 | /* how much to allocate before next GC step */ 30 | #if !defined(GCSTEPSIZE) 31 | /* ~100 small strings */ 32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) 33 | #endif 34 | 35 | 36 | /* 37 | ** Possible states of the Garbage Collector 38 | */ 39 | #define GCSpropagate 0 40 | #define GCSatomic 1 41 | #define GCSswpallgc 2 42 | #define GCSswpfinobj 3 43 | #define GCSswptobefnz 4 44 | #define GCSswpend 5 45 | #define GCScallfin 6 46 | #define GCSpause 7 47 | 48 | 49 | #define issweepphase(g) \ 50 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 51 | 52 | 53 | /* 54 | ** macro to tell when main invariant (white objects cannot point to black 55 | ** ones) must be kept. During a collection, the sweep 56 | ** phase may break the invariant, as objects turned white may point to 57 | ** still-black objects. The invariant is restored when sweep ends and 58 | ** all objects are white again. 59 | */ 60 | 61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 62 | 63 | 64 | /* 65 | ** some useful bit tricks 66 | */ 67 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 68 | #define setbits(x,m) ((x) |= (m)) 69 | #define testbits(x,m) ((x) & (m)) 70 | #define bitmask(b) (1<<(b)) 71 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 72 | #define l_setbit(x,b) setbits(x, bitmask(b)) 73 | #define resetbit(x,b) resetbits(x, bitmask(b)) 74 | #define testbit(x,b) testbits(x, bitmask(b)) 75 | 76 | 77 | /* Layout for bit use in 'marked' field: */ 78 | #define WHITE0BIT 0 /* object is white (type 0) */ 79 | #define WHITE1BIT 1 /* object is white (type 1) */ 80 | #define BLACKBIT 2 /* object is black */ 81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ 82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ 83 | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 85 | 86 | 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) 89 | #define isgray(x) /* neither white nor black */ \ 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 91 | 92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 93 | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 97 | 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) 100 | 101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 102 | 103 | 104 | /* 105 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' 106 | ** allows some adjustments to be done only when needed. macro 107 | ** 'condchangemem' is used only for heavy tests (forcing a full 108 | ** GC cycle on every opportunity) 109 | */ 110 | #define luaC_condGC(L,pre,pos) \ 111 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 112 | condchangemem(L,pre,pos); } 113 | 114 | /* more often than not, 'pre'/'pos' are empty */ 115 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) 116 | 117 | 118 | #define luaC_barrier(L,p,v) ( \ 119 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 120 | luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) 121 | 122 | #define luaC_barrierback(L,p,v) ( \ 123 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 124 | luaC_barrierback_(L,p) : cast_void(0)) 125 | 126 | #define luaC_objbarrier(L,p,o) ( \ 127 | (isblack(p) && iswhite(o)) ? \ 128 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 129 | 130 | #define luaC_upvalbarrier(L,uv) ( \ 131 | (iscollectable((uv)->v) && !upisopen(uv)) ? \ 132 | luaC_upvalbarrier_(L,uv) : cast_void(0)) 133 | 134 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 135 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 136 | LUAI_FUNC void luaC_step (lua_State *L); 137 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 138 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 139 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 140 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 141 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); 142 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); 143 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 144 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); 145 | 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove _PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {"_G", luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {LUA_LVJITLIBNAME, luaopen_lvjit}, 54 | #if defined(LUA_COMPAT_BITLIB) 55 | {LUA_BITLIBNAME, luaopen_bit32}, 56 | #endif 57 | {NULL, NULL} 58 | }; 59 | 60 | 61 | LUALIB_API void luaL_openlibs (lua_State *L) { 62 | const luaL_Reg *lib; 63 | /* "require" functions from 'loadedlibs' and set results to global table */ 64 | for (lib = loadedlibs; lib->func; lib++) { 65 | luaL_requiref(L, lib->name, lib->func, 1); 66 | lua_pop(L, 1); /* remove lib */ 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /lua/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | 17 | #if !defined(LUA_ENV) 18 | #define LUA_ENV "_ENV" 19 | #endif 20 | 21 | 22 | /* 23 | * WARNING: if you change the order of this enumeration, 24 | * grep "ORDER RESERVED" 25 | */ 26 | enum RESERVED { 27 | /* terminal symbols denoted by reserved words */ 28 | TK_AND = FIRST_RESERVED, TK_BREAK, 29 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 30 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 31 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 32 | /* other terminal symbols */ 33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 34 | TK_SHL, TK_SHR, 35 | TK_DBCOLON, TK_EOS, 36 | TK_FLT, TK_INT, TK_NAME, TK_STRING 37 | }; 38 | 39 | /* number of reserved words */ 40 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | lua_Integer i; 46 | TString *ts; 47 | } SemInfo; /* semantics information */ 48 | 49 | 50 | typedef struct Token { 51 | int token; 52 | SemInfo seminfo; 53 | } Token; 54 | 55 | 56 | /* state of the lexer plus state of the parser when shared by all 57 | functions */ 58 | typedef struct LexState { 59 | int current; /* current character (charint) */ 60 | int linenumber; /* input line counter */ 61 | int lastline; /* line of last token 'consumed' */ 62 | Token t; /* current token */ 63 | Token lookahead; /* look ahead token */ 64 | struct FuncState *fs; /* current function (parser) */ 65 | struct lua_State *L; 66 | ZIO *z; /* input stream */ 67 | Mbuffer *buff; /* buffer for tokens */ 68 | Table *h; /* to avoid collection/reuse strings */ 69 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 70 | TString *source; /* current source name */ 71 | TString *envn; /* environment variable name */ 72 | } LexState; 73 | 74 | 75 | LUAI_FUNC void luaX_init (lua_State *L); 76 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 77 | TString *source, int firstchar); 78 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 79 | LUAI_FUNC void luaX_next (LexState *ls); 80 | LUAI_FUNC int luaX_lookahead (LexState *ls); 81 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 82 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 83 | 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /lua/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | 26 | /* 27 | ** About the realloc function: 28 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 29 | ** ('osize' is the old size, 'nsize' is the new size) 30 | ** 31 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no 32 | ** matter 'x'). 33 | ** 34 | ** * frealloc(ud, p, x, 0) frees the block 'p' 35 | ** (in this specific case, frealloc must return NULL); 36 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 37 | ** (which is equivalent to free(NULL) in ISO C) 38 | ** 39 | ** frealloc returns NULL if it cannot create or reallocate the area 40 | ** (any reallocation to an equal or smaller size cannot fail!) 41 | */ 42 | 43 | 44 | 45 | #define MINSIZEARRAY 4 46 | 47 | 48 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 49 | int limit, const char *what) { 50 | void *newblock; 51 | int newsize; 52 | if (*size >= limit/2) { /* cannot double it? */ 53 | if (*size >= limit) /* cannot grow even a little? */ 54 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 55 | newsize = limit; /* still have at least one free place */ 56 | } 57 | else { 58 | newsize = (*size)*2; 59 | if (newsize < MINSIZEARRAY) 60 | newsize = MINSIZEARRAY; /* minimum size */ 61 | } 62 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 63 | *size = newsize; /* update only when everything else is OK */ 64 | return newblock; 65 | } 66 | 67 | 68 | l_noret luaM_toobig (lua_State *L) { 69 | luaG_runerror(L, "memory allocation error: block too big"); 70 | } 71 | 72 | 73 | 74 | /* 75 | ** generic allocation routine. 76 | */ 77 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 78 | void *newblock; 79 | global_State *g = G(L); 80 | size_t realosize = (block) ? osize : 0; 81 | lua_assert((realosize == 0) == (block == NULL)); 82 | #if defined(HARDMEMTESTS) 83 | if (nsize > realosize && g->gcrunning) 84 | luaC_fullgc(L, 1); /* force a GC whenever possible */ 85 | #endif 86 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 87 | if (newblock == NULL && nsize > 0) { 88 | lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ 89 | if (g->version) { /* is state fully built? */ 90 | luaC_fullgc(L, 1); /* try to free some memory... */ 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 92 | } 93 | if (newblock == NULL) 94 | luaD_throw(L, LUA_ERRMEM); 95 | } 96 | lua_assert((nsize == 0) == (newblock == NULL)); 97 | g->GCdebt = (g->GCdebt + nsize) - realosize; 98 | return newblock; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /lua/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | /* 18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where 19 | ** each element has size 'e'. In case of arithmetic overflow of the 20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because 21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). 22 | ** 23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 24 | ** comparison avoids a runtime comparison when overflow cannot occur. 25 | ** The compiler should be able to optimize the real test by itself, but 26 | ** when it does it, it may give a warning about "comparison is always 27 | ** false due to limited range of data type"; the +1 tricks the compiler, 28 | ** avoiding this warning but also this optimization.) 29 | */ 30 | #define luaM_reallocv(L,b,on,n,e) \ 31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ 32 | ? luaM_toobig(L) : cast_void(0)) , \ 33 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) 34 | 35 | /* 36 | ** Arrays of chars do not need any test 37 | */ 38 | #define luaM_reallocvchar(L,b,on,n) \ 39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 40 | 41 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 42 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 43 | #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) 44 | 45 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 46 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 47 | #define luaM_newvector(L,n,t) \ 48 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 49 | 50 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 51 | 52 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 53 | if ((nelems)+1 > (size)) \ 54 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 55 | 56 | #define luaM_reallocvector(L, v,oldn,n,t) \ 57 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 58 | 59 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 60 | 61 | /* not to be called directly */ 62 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 63 | size_t size); 64 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 65 | size_t size_elem, int limit, 66 | const char *what); 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /lua/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lopcodes.h" 16 | 17 | 18 | /* ORDER OP */ 19 | 20 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { 21 | "MOVE", 22 | "LOADK", 23 | "LOADKX", 24 | "LOADBOOL", 25 | "LOADNIL", 26 | "GETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "SETTABUP", 30 | "SETUPVAL", 31 | "SETTABLE", 32 | "NEWTABLE", 33 | "SELF", 34 | "ADD", 35 | "SUB", 36 | "MUL", 37 | "MOD", 38 | "POW", 39 | "DIV", 40 | "IDIV", 41 | "BAND", 42 | "BOR", 43 | "BXOR", 44 | "SHL", 45 | "SHR", 46 | "UNM", 47 | "BNOT", 48 | "NOT", 49 | "LEN", 50 | "CONCAT", 51 | "JMP", 52 | "EQ", 53 | "LT", 54 | "LE", 55 | "TEST", 56 | "TESTSET", 57 | "CALL", 58 | "TAILCALL", 59 | "RETURN", 60 | "FORLOOP", 61 | "FORPREP", 62 | "TFORCALL", 63 | "TFORLOOP", 64 | "SETLIST", 65 | "CLOSURE", 66 | "VARARG", 67 | "EXTRAARG", 68 | NULL 69 | }; 70 | 71 | 72 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 73 | 74 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 75 | /* T A B C mode opcode */ 76 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 77 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 78 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ 79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 80 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ 81 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 82 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ 83 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 84 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ 85 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 86 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 87 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 88 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ 96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ 97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ 98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ 99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ 100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ 101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ 103 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 104 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 105 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 106 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 107 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 108 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 109 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 110 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ 111 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 112 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 113 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 114 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 115 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 116 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 117 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 118 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 119 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 120 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 121 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 122 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /lua/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression and variable descriptor. 17 | ** Code generation for variables and expressions can be delayed to allow 18 | ** optimizations; An 'expdesc' structure describes a potentially-delayed 19 | ** variable/expression. It has a description of its "main" value plus a 20 | ** list of conditional jumps that can also produce its value (generated 21 | ** by short-circuit operators 'and'/'or'). 22 | */ 23 | 24 | /* kinds of variables/expressions */ 25 | typedef enum { 26 | VVOID, /* when 'expdesc' describes the last expression a list, 27 | this kind means an empty list (so, no expression) */ 28 | VNIL, /* constant nil */ 29 | VTRUE, /* constant true */ 30 | VFALSE, /* constant false */ 31 | VK, /* constant in 'k'; info = index of constant in 'k' */ 32 | VKFLT, /* floating constant; nval = numerical float value */ 33 | VKINT, /* integer constant; nval = numerical integer value */ 34 | VNONRELOC, /* expression has its value in a fixed register; 35 | info = result register */ 36 | VLOCAL, /* local variable; info = local register */ 37 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 38 | VINDEXED, /* indexed variable; 39 | ind.vt = whether 't' is register or upvalue; 40 | ind.t = table register or upvalue; 41 | ind.idx = key's R/K index */ 42 | VJMP, /* expression is a test/comparison; 43 | info = pc of corresponding jump instruction */ 44 | VRELOCABLE, /* expression can put result in any register; 45 | info = instruction pc */ 46 | VCALL, /* expression is a function call; info = instruction pc */ 47 | VVARARG /* vararg expression; info = instruction pc */ 48 | } expkind; 49 | 50 | 51 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 52 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 53 | 54 | typedef struct expdesc { 55 | expkind k; 56 | union { 57 | lua_Integer ival; /* for VKINT */ 58 | lua_Number nval; /* for VKFLT */ 59 | int info; /* for generic use */ 60 | struct { /* for indexed variables (VINDEXED) */ 61 | short idx; /* index (R/K) */ 62 | lu_byte t; /* table (register or upvalue) */ 63 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 64 | } ind; 65 | } u; 66 | int t; /* patch list of 'exit when true' */ 67 | int f; /* patch list of 'exit when false' */ 68 | } expdesc; 69 | 70 | 71 | /* description of active local variable */ 72 | typedef struct Vardesc { 73 | short idx; /* variable index in stack */ 74 | } Vardesc; 75 | 76 | 77 | /* description of pending goto statements and label statements */ 78 | typedef struct Labeldesc { 79 | TString *name; /* label identifier */ 80 | int pc; /* position in code */ 81 | int line; /* line where it appeared */ 82 | lu_byte nactvar; /* local level where it appears in current block */ 83 | } Labeldesc; 84 | 85 | 86 | /* list of labels or gotos */ 87 | typedef struct Labellist { 88 | Labeldesc *arr; /* array */ 89 | int n; /* number of entries in use */ 90 | int size; /* array size */ 91 | } Labellist; 92 | 93 | 94 | /* dynamic structures used by the parser */ 95 | typedef struct Dyndata { 96 | struct { /* list of active local variables */ 97 | Vardesc *arr; 98 | int n; 99 | int size; 100 | } actvar; 101 | Labellist gt; /* list of pending gotos */ 102 | Labellist label; /* list of active labels */ 103 | } Dyndata; 104 | 105 | 106 | /* control of blocks */ 107 | struct BlockCnt; /* defined in lparser.c */ 108 | 109 | 110 | /* state needed to generate code for a given function */ 111 | typedef struct FuncState { 112 | Proto *f; /* current function header */ 113 | struct FuncState *prev; /* enclosing function */ 114 | struct LexState *ls; /* lexical state */ 115 | struct BlockCnt *bl; /* chain of current blocks */ 116 | int pc; /* next position to code (equivalent to 'ncode') */ 117 | int lasttarget; /* 'label' of last 'jump label' */ 118 | int jpc; /* list of pending jumps to 'pc' */ 119 | int nk; /* number of elements in 'k' */ 120 | int np; /* number of elements in 'p' */ 121 | int firstlocal; /* index of first local var (in Dyndata array) */ 122 | short nlocvars; /* number of elements in 'f->locvars' */ 123 | lu_byte nactvar; /* number of active local variables */ 124 | lu_byte nups; /* number of upvalues */ 125 | lu_byte freereg; /* first free register */ 126 | } FuncState; 127 | 128 | 129 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 130 | Dyndata *dyd, const char *name, int firstchar); 131 | 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 16 | 17 | #define sizeludata(l) (sizeof(union UUdata) + (l)) 18 | #define sizeudata(u) sizeludata((u)->len) 19 | 20 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 21 | (sizeof(s)/sizeof(char))-1)) 22 | 23 | 24 | /* 25 | ** test whether a string is a reserved word 26 | */ 27 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) 28 | 29 | 30 | /* 31 | ** equality for short strings, which are always internalized 32 | */ 33 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) 34 | 35 | 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 37 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40 | LUAI_FUNC void luaS_clearcache (global_State *g); 41 | LUAI_FUNC void luaS_init (lua_State *L); 42 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 43 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 44 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 45 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 46 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->i_key.nk.next) 16 | 17 | 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) 20 | 21 | /* 22 | ** writable version of 'gkey'; allows updates to individual fields, 23 | ** but not to the whole (which has incompatible type) 24 | */ 25 | #define wgkey(n) (&(n)->i_key.nk) 26 | 27 | #define invalidateTMcache(t) ((t)->flags = 0) 28 | 29 | 30 | /* returns the key, given the value of a table entry */ 31 | #define keyfromval(v) \ 32 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 33 | 34 | 35 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 36 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 37 | TValue *value); 38 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 39 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 40 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 41 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 42 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 43 | LUAI_FUNC Table *luaH_new (lua_State *L); 44 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 45 | unsigned int nhsize); 46 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 47 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 48 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 49 | LUAI_FUNC int luaH_getn (Table *t); 50 | 51 | 52 | #if defined(LUA_DEBUG) 53 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 54 | LUAI_FUNC int luaH_isdummy (Node *n); 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lua/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | #include "lstring.h" 22 | #include "ltable.h" 23 | #include "ltm.h" 24 | #include "lvm.h" 25 | 26 | 27 | static const char udatatypename[] = "userdata"; 28 | 29 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { 30 | "no value", 31 | "nil", "boolean", udatatypename, "number", 32 | "string", "table", "function", udatatypename, "thread", 33 | "proto" /* this last case is used for tests only */ 34 | }; 35 | 36 | 37 | void luaT_init (lua_State *L) { 38 | static const char *const luaT_eventname[] = { /* ORDER TM */ 39 | "__index", "__newindex", 40 | "__gc", "__mode", "__len", "__eq", 41 | "__add", "__sub", "__mul", "__mod", "__pow", 42 | "__div", "__idiv", 43 | "__band", "__bor", "__bxor", "__shl", "__shr", 44 | "__unm", "__bnot", "__lt", "__le", 45 | "__concat", "__call" 46 | }; 47 | int i; 48 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 50 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 51 | } 52 | } 53 | 54 | 55 | /* 56 | ** function to be used with macro "fasttm": optimized for absence of 57 | ** tag methods 58 | */ 59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 60 | const TValue *tm = luaH_getshortstr(events, ename); 61 | lua_assert(event <= TM_EQ); 62 | if (ttisnil(tm)) { /* no tag method? */ 63 | events->flags |= cast_byte(1u<metatable; 75 | break; 76 | case LUA_TUSERDATA: 77 | mt = uvalue(o)->metatable; 78 | break; 79 | default: 80 | mt = G(L)->mt[ttnov(o)]; 81 | } 82 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); 83 | } 84 | 85 | 86 | /* 87 | ** Return the name of the type of an object. For tables and userdata 88 | ** with metatable, use their '__name' metafield, if present. 89 | */ 90 | const char *luaT_objtypename (lua_State *L, const TValue *o) { 91 | Table *mt; 92 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || 93 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { 94 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); 95 | if (ttisstring(name)) /* is '__name' a string? */ 96 | return getstr(tsvalue(name)); /* use it as type name */ 97 | } 98 | return ttypename(ttnov(o)); /* else use standard type name */ 99 | } 100 | 101 | 102 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 103 | const TValue *p2, TValue *p3, int hasres) { 104 | ptrdiff_t result = savestack(L, p3); 105 | StkId func = L->top; 106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 107 | setobj2s(L, func + 1, p1); /* 1st argument */ 108 | setobj2s(L, func + 2, p2); /* 2nd argument */ 109 | L->top += 3; 110 | if (!hasres) /* no result? 'p3' is third argument */ 111 | setobj2s(L, L->top++, p3); /* 3rd argument */ 112 | /* metamethod may yield only when called from Lua code */ 113 | if (isLua(L->ci)) 114 | luaD_call(L, func, hasres); 115 | else 116 | luaD_callnoyield(L, func, hasres); 117 | if (hasres) { /* if has result, move it to its place */ 118 | p3 = restorestack(L, result); 119 | setobjs2s(L, p3, --L->top); 120 | } 121 | } 122 | 123 | 124 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 125 | StkId res, TMS event) { 126 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 127 | if (ttisnil(tm)) 128 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 129 | if (ttisnil(tm)) return 0; 130 | luaT_callTM(L, tm, p1, p2, res, 1); 131 | return 1; 132 | } 133 | 134 | 135 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 136 | StkId res, TMS event) { 137 | if (!luaT_callbinTM(L, p1, p2, res, event)) { 138 | switch (event) { 139 | case TM_CONCAT: 140 | luaG_concaterror(L, p1, p2); 141 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ 142 | case TM_BAND: case TM_BOR: case TM_BXOR: 143 | case TM_SHL: case TM_SHR: case TM_BNOT: { 144 | lua_Number dummy; 145 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) 146 | luaG_tointerror(L, p1, p2); 147 | else 148 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 149 | } 150 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 151 | default: 152 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 153 | } 154 | } 155 | } 156 | 157 | 158 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 159 | TMS event) { 160 | if (!luaT_callbinTM(L, p1, p2, L->top, event)) 161 | return -1; /* no metamethod */ 162 | else 163 | return !l_isfalse(L->top); 164 | } 165 | 166 | -------------------------------------------------------------------------------- /lua/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_N /* number of elements in the enum */ 44 | } TMS; 45 | 46 | 47 | 48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 50 | 51 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 52 | 53 | #define ttypename(x) luaT_typenames_[(x) + 1] 54 | 55 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 56 | 57 | 58 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 59 | 60 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 61 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 62 | TMS event); 63 | LUAI_FUNC void luaT_init (lua_State *L); 64 | 65 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 66 | const TValue *p2, TValue *p3, int hasres); 67 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 68 | StkId res, TMS event); 69 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 70 | StkId res, TMS event); 71 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 72 | const TValue *p2, TMS event); 73 | 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_UTF8LIBNAME "utf8" 33 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 34 | 35 | #define LUA_BITLIBNAME "bit32" 36 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | #define LUA_LVJITLIBNAME "lvjit" 48 | LUAMOD_API int (luaopen_lvjit) (lua_State *L); 49 | 50 | /* open all previous libraries */ 51 | LUALIB_API void (luaL_openlibs) (lua_State *L); 52 | 53 | 54 | 55 | #if !defined(lua_assert) 56 | #define lua_assert(x) ((void)0) 57 | #endif 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lua/luav.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Lua Vermelha JIT control API 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | #ifndef luav_h 7 | #define luav_h 8 | 9 | #include "lua.h" 10 | 11 | /* 12 | ** Function flags for Lua Vermelha JIT 13 | */ 14 | #define LUA_NOJITFLAGS 0x0 15 | #define LUA_JITBLACKLIST 0x1 /* shouldn't (re)compile function */ 16 | 17 | /* 18 | ** Check if the given JIT flags is set for the function at the given index. 19 | */ 20 | LUA_API int lua_checkjitflags(lua_State* L, int index, int flags); 21 | 22 | /* 23 | ** Set the given JIT flags for the function at the given index. 24 | */ 25 | LUA_API void lua_setjitflags(lua_State* L, int index, int flags); 26 | 27 | /* 28 | ** Clear the given JIT flags for the function at the given index. 29 | */ 30 | LUA_API void lua_clearjitflags(lua_State* L, int index, int flags); 31 | 32 | /* 33 | ** Returns the initial value of Lua function call counters. 34 | */ 35 | LUA_API int lua_initcallcounter(lua_State* L); 36 | 37 | /* 38 | ** Check if the function at the given index has been compiled. Returns 1 if 39 | ** true, 0 otherwise. 40 | */ 41 | LUA_API int lua_iscompiled(lua_State* L, int index); 42 | 43 | /* 44 | ** Compile the Lua function at the given index. Returns 1 if succesfull, 45 | ** 0 otherwise. 46 | */ 47 | LUA_API int lua_compile(lua_State* L, int index); 48 | 49 | #endif /* luav_h */ 50 | -------------------------------------------------------------------------------- /lua/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.44 2015/11/02 16:09:30 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lundump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstring.h" 23 | #include "lundump.h" 24 | #include "lzio.h" 25 | 26 | 27 | #if !defined(luai_verifycode) 28 | #define luai_verifycode(L,b,f) /* empty */ 29 | #endif 30 | 31 | 32 | typedef struct { 33 | lua_State *L; 34 | ZIO *Z; 35 | const char *name; 36 | } LoadState; 37 | 38 | 39 | static l_noret error(LoadState *S, const char *why) { 40 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); 41 | luaD_throw(S->L, LUA_ERRSYNTAX); 42 | } 43 | 44 | 45 | /* 46 | ** All high-level loads go through LoadVector; you can change it to 47 | ** adapt to the endianness of the input 48 | */ 49 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) 50 | 51 | static void LoadBlock (LoadState *S, void *b, size_t size) { 52 | if (luaZ_read(S->Z, b, size) != 0) 53 | error(S, "truncated"); 54 | } 55 | 56 | 57 | #define LoadVar(S,x) LoadVector(S,&x,1) 58 | 59 | 60 | static lu_byte LoadByte (LoadState *S) { 61 | lu_byte x; 62 | LoadVar(S, x); 63 | return x; 64 | } 65 | 66 | 67 | static int LoadInt (LoadState *S) { 68 | int x; 69 | LoadVar(S, x); 70 | return x; 71 | } 72 | 73 | 74 | static lua_Number LoadNumber (LoadState *S) { 75 | lua_Number x; 76 | LoadVar(S, x); 77 | return x; 78 | } 79 | 80 | 81 | static lua_Integer LoadInteger (LoadState *S) { 82 | lua_Integer x; 83 | LoadVar(S, x); 84 | return x; 85 | } 86 | 87 | 88 | static TString *LoadString (LoadState *S) { 89 | size_t size = LoadByte(S); 90 | if (size == 0xFF) 91 | LoadVar(S, size); 92 | if (size == 0) 93 | return NULL; 94 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 95 | char buff[LUAI_MAXSHORTLEN]; 96 | LoadVector(S, buff, size); 97 | return luaS_newlstr(S->L, buff, size); 98 | } 99 | else { /* long string */ 100 | TString *ts = luaS_createlngstrobj(S->L, size); 101 | LoadVector(S, getstr(ts), size); /* load directly in final place */ 102 | return ts; 103 | } 104 | } 105 | 106 | 107 | static void LoadCode (LoadState *S, Proto *f) { 108 | int n = LoadInt(S); 109 | f->code = luaM_newvector(S->L, n, Instruction); 110 | f->sizecode = n; 111 | LoadVector(S, f->code, n); 112 | } 113 | 114 | 115 | static void LoadFunction(LoadState *S, Proto *f, TString *psource); 116 | 117 | 118 | static void LoadConstants (LoadState *S, Proto *f) { 119 | int i; 120 | int n = LoadInt(S); 121 | f->k = luaM_newvector(S->L, n, TValue); 122 | f->sizek = n; 123 | for (i = 0; i < n; i++) 124 | setnilvalue(&f->k[i]); 125 | for (i = 0; i < n; i++) { 126 | TValue *o = &f->k[i]; 127 | int t = LoadByte(S); 128 | switch (t) { 129 | case LUA_TNIL: 130 | setnilvalue(o); 131 | break; 132 | case LUA_TBOOLEAN: 133 | setbvalue(o, LoadByte(S)); 134 | break; 135 | case LUA_TNUMFLT: 136 | setfltvalue(o, LoadNumber(S)); 137 | break; 138 | case LUA_TNUMINT: 139 | setivalue(o, LoadInteger(S)); 140 | break; 141 | case LUA_TSHRSTR: 142 | case LUA_TLNGSTR: 143 | setsvalue2n(S->L, o, LoadString(S)); 144 | break; 145 | default: 146 | lua_assert(0); 147 | } 148 | } 149 | } 150 | 151 | 152 | static void LoadProtos (LoadState *S, Proto *f) { 153 | int i; 154 | int n = LoadInt(S); 155 | f->p = luaM_newvector(S->L, n, Proto *); 156 | f->sizep = n; 157 | for (i = 0; i < n; i++) 158 | f->p[i] = NULL; 159 | for (i = 0; i < n; i++) { 160 | f->p[i] = luaF_newproto(S->L); 161 | LoadFunction(S, f->p[i], f->source); 162 | } 163 | } 164 | 165 | 166 | static void LoadUpvalues (LoadState *S, Proto *f) { 167 | int i, n; 168 | n = LoadInt(S); 169 | f->upvalues = luaM_newvector(S->L, n, Upvaldesc); 170 | f->sizeupvalues = n; 171 | for (i = 0; i < n; i++) 172 | f->upvalues[i].name = NULL; 173 | for (i = 0; i < n; i++) { 174 | f->upvalues[i].instack = LoadByte(S); 175 | f->upvalues[i].idx = LoadByte(S); 176 | } 177 | } 178 | 179 | 180 | static void LoadDebug (LoadState *S, Proto *f) { 181 | int i, n; 182 | n = LoadInt(S); 183 | f->lineinfo = luaM_newvector(S->L, n, int); 184 | f->sizelineinfo = n; 185 | LoadVector(S, f->lineinfo, n); 186 | n = LoadInt(S); 187 | f->locvars = luaM_newvector(S->L, n, LocVar); 188 | f->sizelocvars = n; 189 | for (i = 0; i < n; i++) 190 | f->locvars[i].varname = NULL; 191 | for (i = 0; i < n; i++) { 192 | f->locvars[i].varname = LoadString(S); 193 | f->locvars[i].startpc = LoadInt(S); 194 | f->locvars[i].endpc = LoadInt(S); 195 | } 196 | n = LoadInt(S); 197 | for (i = 0; i < n; i++) 198 | f->upvalues[i].name = LoadString(S); 199 | } 200 | 201 | 202 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { 203 | f->source = LoadString(S); 204 | if (f->source == NULL) /* no source in dump? */ 205 | f->source = psource; /* reuse parent's source */ 206 | f->linedefined = LoadInt(S); 207 | f->lastlinedefined = LoadInt(S); 208 | f->numparams = LoadByte(S); 209 | f->is_vararg = LoadByte(S); 210 | f->maxstacksize = LoadByte(S); 211 | LoadCode(S, f); 212 | LoadConstants(S, f); 213 | LoadUpvalues(S, f); 214 | LoadProtos(S, f); 215 | LoadDebug(S, f); 216 | } 217 | 218 | 219 | static void checkliteral (LoadState *S, const char *s, const char *msg) { 220 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 221 | size_t len = strlen(s); 222 | LoadVector(S, buff, len); 223 | if (memcmp(s, buff, len) != 0) 224 | error(S, msg); 225 | } 226 | 227 | 228 | static void fchecksize (LoadState *S, size_t size, const char *tname) { 229 | if (LoadByte(S) != size) 230 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); 231 | } 232 | 233 | 234 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) 235 | 236 | static void checkHeader (LoadState *S) { 237 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ 238 | if (LoadByte(S) != LUAC_VERSION) 239 | error(S, "version mismatch in"); 240 | if (LoadByte(S) != LUAC_FORMAT) 241 | error(S, "format mismatch in"); 242 | checkliteral(S, LUAC_DATA, "corrupted"); 243 | checksize(S, int); 244 | checksize(S, size_t); 245 | checksize(S, Instruction); 246 | checksize(S, lua_Integer); 247 | checksize(S, lua_Number); 248 | if (LoadInteger(S) != LUAC_INT) 249 | error(S, "endianness mismatch in"); 250 | if (LoadNumber(S) != LUAC_NUM) 251 | error(S, "float format mismatch in"); 252 | } 253 | 254 | 255 | /* 256 | ** load precompiled chunk 257 | */ 258 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 259 | LoadState S; 260 | LClosure *cl; 261 | if (*name == '@' || *name == '=') 262 | S.name = name + 1; 263 | else if (*name == LUA_SIGNATURE[0]) 264 | S.name = "binary string"; 265 | else 266 | S.name = name; 267 | S.L = L; 268 | S.Z = Z; 269 | checkHeader(&S); 270 | cl = luaF_newLclosure(L, LoadByte(&S)); 271 | setclLvalue(L, L->top, cl); 272 | luaD_inctop(L); 273 | cl->p = luaF_newproto(L); 274 | LoadFunction(&S, cl->p, NULL); 275 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); 276 | luai_verifycode(L, buff, cl->p); 277 | return cl; 278 | } 279 | 280 | -------------------------------------------------------------------------------- /lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | #define MYINT(s) (s[0]-'0') 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 23 | #define LUAC_FORMAT 0 /* this is the official format */ 24 | 25 | /* load one chunk; from lundump.c */ 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 27 | 28 | /* dump one chunk; from ldump.c */ 29 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 30 | void* data, int strip); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lua/lvapi.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Lua Vermelha JIT control API 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | #include "luav.h" 7 | #include "lvapi.h" 8 | #include "lvjit.h" 9 | 10 | static Proto* getfuncproto(lua_State* L, int index) { 11 | const void* f = lua_topointer(L, index); 12 | return ((const LClosure*)f)->p; 13 | } 14 | 15 | LUA_API int lua_checkjitflags(lua_State* L, int index, int flags) { 16 | int ret = (int)LUA_NOJITFLAGS; 17 | Proto* p = NULL; 18 | lua_lock(L); 19 | p = getfuncproto(L, index); 20 | ret = LUAJ_CHECKJITFLAGS(p, flags); 21 | lua_unlock(L); 22 | return ret; 23 | } 24 | 25 | LUA_API void lua_setjitflags(lua_State* L, int index, int flags) { 26 | lua_lock(L); 27 | Proto* p = getfuncproto(L, index); 28 | LUAJ_SETJITFLAGS(p, flags); 29 | lua_unlock(L); 30 | } 31 | 32 | LUA_API void lua_clearjitflags(lua_State* L, int index, int flags) { 33 | lua_lock(L); 34 | Proto* p = getfuncproto(L, index); 35 | LUAJ_CLEARJITFLAGS(p, flags); 36 | lua_unlock(L); 37 | } 38 | 39 | LUA_API int lua_initcallcounter(lua_State* L) { 40 | (void)L; // not used 41 | return luaJ_initcallcounter(); 42 | } 43 | 44 | LUA_API int lua_iscompiled(lua_State* L, int index) { 45 | int ret = 0; 46 | Proto* p = NULL; 47 | lua_lock(L); 48 | p = getfuncproto(L, index); 49 | ret = LUAJ_ISCOMPILED(p); 50 | lua_unlock(L); 51 | return ret; 52 | } 53 | 54 | LUA_API int lua_compile(lua_State* L, int index) { 55 | int ret = 0; 56 | Proto* p = NULL; 57 | lua_lock(L); 58 | p = getfuncproto(L, index); 59 | ret = luaJ_compile(p); 60 | lua_unlock(L); 61 | return ret; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /lua/lvapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Helper functions and macros for Lua Vermelha JIT control API 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | #ifndef lvapi_h 7 | #define lvapi_h 8 | 9 | #include "luav.h" 10 | 11 | /* 12 | ** Generic getters and setters for JIT flags 13 | */ 14 | #define LUAJ_CHECKJITFLAGS(p, f) ((p)->jitflags & f) 15 | #define LUAJ_SETJITFLAGS(p, f) do { \ 16 | Proto* _p = (p); _p->jitflags = _p->jitflags | f; } while (0) 17 | #define LUAJ_CLEARJITFLAGS(p, f) do { \ 18 | Proto* _p = (p); _p->jitflags = _p->jitflags & (~f); } while(0) 19 | 20 | /* 21 | ** Specific getters and setters for JIT flags 22 | */ 23 | #define LUAJ_ISBLACKLISTED(p) LUAJ_CHECKJITFLAGS(p, LUA_JITBLACKLIST) 24 | #define LUAJ_BLACKLIST(p) LUAJ_SETJITFLAGS(p, LUA_JITBLACKLIST) 25 | #define LUAJ_UNBLACKLIST(p) LUAJ_CLEARJITFLAGS(p, LUA_JITBLACKLIST) 26 | 27 | /* 28 | ** Check if function has been compiled 29 | */ 30 | #define LUAJ_ISCOMPILED(p) ((p)->compiledcode ? 1 : 0) 31 | 32 | #endif /* lvapi_h */ 33 | -------------------------------------------------------------------------------- /lua/lvjit.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Lua Vermelha JIT interface 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | #ifndef lvjit_h 7 | #define lvjit_h 8 | 9 | #include "lobject.h" 10 | 11 | /* 12 | ** Initialize the JIT 13 | */ 14 | int luaJ_initJit(); 15 | 16 | /* 17 | ** Shutdown the JIT 18 | */ 19 | void luaJ_stopJit(); 20 | 21 | /* 22 | ** Given a Lua function's `Proto`, tries to compile it. If successful, 23 | ** returns a pointer to the compiled function body, `NULL` otherwise. 24 | ** This function ignors all JIT flags and does not set `p->compiledcode`. 25 | */ 26 | lua_JitFunction luaJ_invokejit(Proto* p); 27 | 28 | /* 29 | ** Given a Lua function's `Proto`, tries to compile it. If successful, 30 | ** returns 1 and `p->compiledcode` points to the compiled function body. 31 | ** Otherwise, returns 0 and `p->compiledcode` is `NULL`. 32 | */ 33 | int luaJ_compile(Proto* p); 34 | 35 | /* 36 | ** Get the number of times a function must be called before tyring to compile it 37 | */ 38 | unsigned int luaJ_initcallcounter(); 39 | 40 | #endif /* lvjit_h */ 41 | 42 | -------------------------------------------------------------------------------- /lua/lvjitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Library for controlling the Lua Vermelha JIT 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | #include "lua.h" 7 | #include "luav.h" 8 | 9 | #include "lauxlib.h" 10 | #include "lualib.h" 11 | #include "lobject.h" 12 | 13 | static int lvjit_checkjitflags(lua_State* L) { 14 | int flags = lua_tointeger(L, 2); 15 | luaL_checktype(L, 1, LUA_TLCL); 16 | int ret = lua_checkjitflags(L, 1, flags); 17 | lua_pushinteger(L, ret); 18 | 19 | return 1; 20 | } 21 | 22 | int lvjit_setjitflags(lua_State* L) { 23 | int flags = lua_tointeger(L, 2); 24 | luaL_checktype(L, 1, LUA_TLCL); 25 | lua_setjitflags(L, 1, flags); 26 | return 0; 27 | } 28 | 29 | int lvjit_clearjitflags(lua_State* L) { 30 | int flags = lua_tointeger(L, 2); 31 | luaL_checktype(L, 1, LUA_TLCL); 32 | lua_clearjitflags(L, 1, flags); 33 | return 0; 34 | } 35 | 36 | static int lvjit_initcallcounter(lua_State* L) { 37 | int ret = lua_initcallcounter(L); 38 | lua_pushinteger(L, ret); 39 | return 1; 40 | } 41 | 42 | static int lvjit_iscompiled(lua_State* L) { 43 | luaL_checktype(L, 1, LUA_TLCL); 44 | int ret = lua_iscompiled(L, 1); 45 | lua_pushboolean(L, ret); 46 | return 1; 47 | } 48 | 49 | static int lvjit_compile(lua_State* L) { 50 | luaL_checktype(L, 1, LUA_TLCL); 51 | int ret = lua_compile(L, 1); 52 | lua_pushboolean(L, ret); 53 | return 1; 54 | } 55 | 56 | static const luaL_Reg lvjitlib[] = { 57 | {"checkjitflags", lvjit_checkjitflags}, 58 | {"setjitflags", lvjit_setjitflags}, 59 | {"clearjitflags", lvjit_clearjitflags}, 60 | {"initcallcounter", lvjit_initcallcounter}, 61 | {"iscompiled", lvjit_iscompiled}, 62 | {"compile", lvjit_compile}, 63 | /* placeholders for JIT flags */ 64 | {"NOJITFLAGS", NULL}, 65 | {"JITBLACKLIST", NULL}, 66 | {NULL, NULL} 67 | }; 68 | 69 | LUAMOD_API int luaopen_lvjit(lua_State* L) { 70 | luaL_newlib(L, lvjitlib); 71 | lua_pushinteger(L, LUA_NOJITFLAGS); 72 | lua_setfield(L, -2, "NOJITFLAGS"); 73 | lua_pushinteger(L, LUA_JITBLACKLIST); 74 | lua_setfield(L, -2, "JITBLACKLIST"); 75 | return 1; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /lua/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | /* 31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers 32 | ** by flooring them (instead of raising an error if they are not 33 | ** integral values) 34 | */ 35 | #if !defined(LUA_FLOORN2I) 36 | #define LUA_FLOORN2I 0 37 | #endif 38 | 39 | 40 | #define tonumber(o,n) \ 41 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 42 | 43 | #define tointeger(o,i) \ 44 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) 45 | 46 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 47 | 48 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 49 | 50 | 51 | /* 52 | ** fast track for 'gettable': if 't' is a table and 't[k]' is not nil, 53 | ** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise, 54 | ** return 0 (meaning it will have to check metamethod) with 'slot' 55 | ** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise). 56 | ** 'f' is the raw get function to use. 57 | */ 58 | #define luaV_fastget(L,t,k,slot,f) \ 59 | (!ttistable(t) \ 60 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 61 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ 62 | !ttisnil(slot))) /* result not nil? */ 63 | 64 | /* 65 | ** standard implementation for 'gettable' 66 | */ 67 | #define luaV_gettable(L,t,k,v) { const TValue *slot; \ 68 | if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \ 69 | else luaV_finishget(L,t,k,v,slot); } 70 | 71 | 72 | /* 73 | ** Fast track for set table. If 't' is a table and 't[k]' is not nil, 74 | ** call GC barrier, do a raw 't[k]=v', and return true; otherwise, 75 | ** return false with 'slot' equal to NULL (if 't' is not a table) or 76 | ** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro 77 | ** returns true, there is no need to 'invalidateTMcache', because the 78 | ** call is not creating a new entry. 79 | */ 80 | #define luaV_fastset(L,t,k,slot,f,v) \ 81 | (!ttistable(t) \ 82 | ? (slot = NULL, 0) \ 83 | : (slot = f(hvalue(t), k), \ 84 | ttisnil(slot) ? 0 \ 85 | : (luaC_barrierback(L, hvalue(t), v), \ 86 | setobj2t(L, cast(TValue *,slot), v), \ 87 | 1))) 88 | 89 | 90 | #define luaV_settable(L,t,k,v) { const TValue *slot; \ 91 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ 92 | luaV_finishset(L,t,k,v,slot); } 93 | 94 | 95 | 96 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 97 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 98 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 99 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 100 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); 101 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 102 | StkId val, const TValue *slot); 103 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 104 | StkId val, const TValue *slot); 105 | LUAI_FUNC void luaV_finishOp (lua_State *L); 106 | LUAI_FUNC void luaV_execute (lua_State *L); 107 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 108 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); 109 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 110 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 111 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.37 2015/09/08 15:41:05 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /lvjit/LuaTypeDictionary.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (c) Copyright IBM Corp. 2016, 2017 4 | * 5 | * This program and the accompanying materials are made available 6 | * under the terms of the Eclipse Public License v1.0 and 7 | * Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * Contributors: 16 | * Multiple authors (IBM Corp.) - initial implementation and documentation 17 | ******************************************************************************/ 18 | 19 | #ifndef LUATYPEDICTIONARY_HPP 20 | #define LUATYPEDICTIONARY_HPP 21 | 22 | // JitBuilder headers 23 | #include "Jit.hpp" 24 | #include "ilgen/TypeDictionary.hpp" 25 | 26 | // Lua headers 27 | #include "luavm.hpp" 28 | 29 | namespace Lua { class TypeDictionary; } 30 | 31 | /* 32 | ** A TypeDictionary for defining JitBuilder representations of Lua VM types 33 | */ 34 | class Lua::TypeDictionary : public TR::TypeDictionary { 35 | public: 36 | 37 | // struct for caching JitBuilder representations of commonly used VM types 38 | struct LuaTypes { 39 | TR::IlType* lu_byte; 40 | TR::IlType* lua_Integer; 41 | TR::IlType* lua_Unsigned; 42 | TR::IlType* lua_Number; 43 | TR::IlType* Instruction; 44 | TR::IlType* Value; 45 | TR::IlType* TString; 46 | TR::IlType* p_TString; 47 | TR::IlType* TValue; 48 | TR::IlType* StkId; 49 | TR::IlType* Proto; 50 | TR::IlType* LClosure; 51 | TR::IlType* UpVal; 52 | TR::IlType* CallInfo; 53 | TR::IlType* lua_State; 54 | TR::IlType* TMS; 55 | }; 56 | 57 | TypeDictionary(); 58 | 59 | LuaTypes getLuaTypes() { return luaTypes; } 60 | 61 | private: 62 | LuaTypes luaTypes; 63 | }; 64 | 65 | #endif // LUATYPEDICTIONARY_HPP 66 | -------------------------------------------------------------------------------- /lvjit/Makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # (c) Copyright IBM Corp. 2016, 2017 4 | # 5 | # This program and the accompanying materials are made available 6 | # under the terms of the Eclipse Public License v1.0 and 7 | # Apache License v2.0 which accompanies this distribution. 8 | # 9 | # The Eclipse Public License is available at 10 | # http://www.eclipse.org/legal/epl-v10.html 11 | # 12 | # The Apache License v2.0 is available at 13 | # http://www.opensource.org/licenses/apache2.0.php 14 | # 15 | # Contributors: 16 | # Multiple authors (IBM Corp.) - initial implementation and documentation 17 | # 18 | ################################################################################ 19 | 20 | CXX?= g++ 21 | AR?= ar 22 | LD?= ld 23 | MKDIR?= mkdir -p 24 | 25 | ARCH?= x 26 | SUBARCH?= amd64 27 | 28 | STATICLIB_NAME?= liblvjit.a 29 | LVJITOBJ_NAME?= lvjit.o 30 | SHAREDLIB_NAME?= liblvjit.so 31 | 32 | CXX_FLAGS= -std=c++0x -fno-rtti -W -Wall -Wextra -fPIC $(CXX_FLAGS_EXTRA) $(addprefix -I,$(IPATH)) 33 | 34 | # path definitions 35 | 36 | BIN_DIR?= $(PWD) 37 | STATICLIB_DEST?= $(BIN_DIR) 38 | LVJITOBJ_DEST?= $(BIN_DIR) 39 | SHAREDLIB_DEST?= $(BIN_DIR) 40 | OBJS_DIR?= $(BIN_DIR)/objs 41 | 42 | LUA_DIR?= ../ 43 | OMR_DIR?= ../omr 44 | 45 | JITBUILDER_DIR?= $(OMR_DIR)/jitbuilder 46 | JITBUILDER_ARCH_DIR?= $(JITBUILDER_DIR)/$(ARCH) 47 | JITBUILDER_SUBARCH_DIR?= $(JITBUILDER_ARCH_DIR)/$(SUBARCH) 48 | JITBUILDER_LIB_DIR?= $(JITBUILDER_DIR)/release 49 | JITBUILDER_HEADERS?= $(JITBUILDER_LIB_DIR)/include 50 | 51 | OMR_COMPILER_DIR?= $(OMR_DIR)/compiler 52 | OMR_COMPILER_ARCH_DIR?= $(OMR_COMPILER_DIR)/$(ARCH) 53 | OMR_COMPILER_SUBARCH_DIR?= $(OMR_COMPILER_ARCH_DIR)/$(SUBARCH) 54 | 55 | IPATH= $(LUA_DIR) $(JITBUILDER_HEADERS) $(JITBUILDER_SUBARCH_DIR) $(JITBUILDER_ARCH_DIR) $(JITBUILDER_DIR) $(OMR_COMPILER_SUBARCH_DIR) $(OMR_COMPILER_ARCH_DIR) $(OMR_COMPILER_DIR) $(OMR_DIR) 56 | 57 | # file list 58 | 59 | SOURCE_FILES= \ 60 | LuaTypeDictionary.cpp \ 61 | LuaFunctionBuilder.cpp \ 62 | lvjit.cpp 63 | 64 | OBJECT_FILES= $(addprefix $(OBJS_DIR)/, $(subst .cpp,.o,$(SOURCE_FILES))) 65 | STATICLIB_PATH= $(STATICLIB_DEST)/$(STATICLIB_NAME) 66 | LVJITOBJ_PATH= $(LVJITOBJ_DEST)/$(LVJITOBJ_NAME) 67 | SHAREDLIB_PATH= $(SHAREDLIB_DEST)/$(SHAREDLIB_NAME) 68 | 69 | # targets 70 | 71 | .PHONY: default staticlib lvjitobj sharedlib clean cleanall 72 | 73 | default: staticlib 74 | 75 | staticlib: $(STATICLIB_PATH) 76 | $(STATICLIB_NAME): $(STATICLIB_PATH) 77 | $(STATICLIB_PATH): $(OBJECT_FILES) 78 | $(AR) -r $@ $(OBJECT_FILES) 79 | 80 | lvjitobj: $(LVJITOBJ_PATH) 81 | $(LVJITOBJ_NAME): $(LVJITOBJ_PATH) 82 | $(LVJITOBJ_PATH): $(OBJECT_FILES) 83 | $(LD) -Ur -o $@ $(OBJECT_FILES) $(LD_FLAGS_EXTRA) 84 | 85 | sharedlib: $(SHAREDLIB_PATH) 86 | $(SHAREDLIB_NAME): $(SHAREDLIB_PATH) 87 | $(SHAREDLIB_PATH): $(OBJECT_FILES) 88 | $(CXX) -shared -o $@ $(OBJECT_FILES) $(LD_FLAGS_EXTRA) $(JITBUILDER_LIB_DIR)/libjitbuilder.a -ldl 89 | 90 | $(OBJS_DIR)/%.o: %.cpp *.hpp $(OBJS_DIR) 91 | $(CXX) $(CXX_FLAGS) -c $< -o $@ 92 | 93 | $(OBJS_DIR): 94 | $(MKDIR) $@ 95 | 96 | clean: 97 | rm -f $(OBJECT_FILES) 98 | 99 | cleanall: 100 | rm -f $(OBJECT_FILES) $(STATICLIB_PATH) $(SHAREDLIB_PATH) $(LVJITOBJ_PATH) 101 | -------------------------------------------------------------------------------- /lvjit/luavm.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (c) Copyright IBM Corp. 2016, 2017 4 | * 5 | * This program and the accompanying materials are made available 6 | * under the terms of the Eclipse Public License v1.0 and 7 | * Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * Contributors: 16 | * Multiple authors (IBM Corp.) - initial implementation and documentation 17 | ******************************************************************************/ 18 | 19 | #ifndef LUAVM_HPP 20 | #define LUAVM_HPP 21 | 22 | /* 23 | This file includes all the Lua VM headers that are neede by the 24 | Lua Vermelha JIT compiler. This header can then be included in 25 | other parts of the JIT where access to the VM is needed. This is 26 | done to hide some of the work needed to properly interface the 27 | VM and the JIT. 28 | 29 | When the `LUA_C_LINKAGE` macro is defined, all the includes are 30 | wrapped in an `extern "C"` block to prevent name mangling when 31 | linking the JIT with the VM compiled as C. 32 | */ 33 | 34 | #ifdef LUA_C_LINKAGE 35 | extern "C" { 36 | #endif 37 | 38 | // Lua headers 39 | #include "lua/lopcodes.h" 40 | #include "lua/lobject.h" 41 | #include "lua/lfunc.h" 42 | #include "lua/ltm.h" 43 | #include "lua/lstate.h" 44 | #include "lua/ltable.h" 45 | #include "lua/ltm.h" 46 | #include "lua/ldo.h" 47 | #include "lua/lvm.h" 48 | #include "lua/lgc.h" 49 | #include "lua/ldebug.h" 50 | #include "lua/luav.h" 51 | #include "lua/lvjit.h" 52 | 53 | #ifdef LUA_C_LINKAGE 54 | } 55 | #endif 56 | 57 | #endif // LUAVM_HPP 58 | 59 | -------------------------------------------------------------------------------- /lvjit/lvjit.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (c) Copyright IBM Corp. 2016, 2017 4 | * 5 | * This program and the accompanying materials are made available 6 | * under the terms of the Eclipse Public License v1.0 and 7 | * Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * Contributors: 16 | * Multiple authors (IBM Corp.) - initial implementation and documentation 17 | ******************************************************************************/ 18 | 19 | // Lua Vermelha headers 20 | #include "luavm.hpp" 21 | #include "LuaTypeDictionary.hpp" 22 | #include "LuaFunctionBuilder.hpp" 23 | 24 | // JitBuilder headers 25 | #include "Jit.hpp" 26 | 27 | // OMR headers 28 | #include "ilgen/TypeDictionary.hpp" 29 | 30 | int luaJ_initJit() { 31 | return initializeJit() ? 0 : 1; 32 | } 33 | 34 | void luaJ_stopJit() { 35 | shutdownJit(); 36 | } 37 | 38 | lua_JitFunction luaJ_invokejit(Proto* p) { 39 | Lua::TypeDictionary types; 40 | uint8_t* entry = nullptr; 41 | Lua::FunctionBuilder f(p, &types); 42 | 43 | uint32_t rc = compileMethodBuilder(&f, &entry); 44 | 45 | if (rc == 0) { 46 | return (lua_JitFunction)entry; 47 | } 48 | else { 49 | return nullptr; 50 | } 51 | } 52 | 53 | int luaJ_compile(Proto* p) { 54 | lua_JitFunction f = luaJ_invokejit(p); 55 | 56 | if (f) { 57 | p->compiledcode = f; 58 | return 1; 59 | } 60 | else { 61 | p->compiledcode = NULL; 62 | return 0; 63 | } 64 | } 65 | 66 | unsigned int luaJ_initcallcounter() { 67 | return 100; 68 | } 69 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha Testing 2 | 3 | This directory contains tests cases for Lua Vermelha. These are further 4 | divided into sub-directories. 5 | 6 | ## opcode 7 | 8 | The `opcode` directory contains small test cases that exercise 9 | each implemented opcode. 10 | 11 | Each test case is a small Lua script. A test case can be executed by 12 | running a specific test file using `luav`. 13 | 14 | For convenience there is a `all.lua` file that executes all other 15 | test files in the directory. 16 | 17 | ## lvjit 18 | 19 | The `lvjit` directory contains test cases that exercise the JIT control 20 | functions exposed by the Lua Vermelha C API. 21 | 22 | ## control 23 | 24 | The `control` directory contains test cases that exercise the `lvjit` 25 | library for controlling the JIT compiler from Lua code. 26 | 27 | -------------------------------------------------------------------------------- /test/README_zh.md: -------------------------------------------------------------------------------- 1 | # Lua Vermelha 测试 2 | 3 | 本目录存放Lua Vermelha的测试用例代码。它们各自在子目录下。 4 | 5 | ## opcode 6 | 7 | `opcode` 目录存放着检查每个已经实现了的opcode的小型的测试用例 8 | 9 | 每个测试用例就是一段小型的Lua脚本。每个测试用例都可以用 `luav` 来单独执行。 10 | 11 | 为了方便起见,有一个 `all.lua` 脚本用来执行本目录中所有的其他测试用例。 12 | 13 | ## lvjit 14 | 15 | `lvjit` 目录存放着检查JIT控制函数测试用例,这些JIT控制函数是通过Lua Vermelha C语言API提供的。 16 | 17 | ## control 18 | 19 | `control` 目录存放着检查 `lvjit` 库里面的Lua实现的JIT控制函数。 20 | 21 | -------------------------------------------------------------------------------- /test/benchmark/loop_add_double_register_with_double_constants.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | local asserts = require "asserts" 21 | local jit = require "lvjit" 22 | local assert_equal = asserts.assert_equal 23 | local assert_compile = asserts.assert_compile 24 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 25 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 26 | 27 | -- define test function 28 | local function sum_int() 29 | local r = 0.0 30 | for index = 0,200,1 do 31 | for index2 = 0,500000,1 do 32 | r = r + 1.0 33 | r = r + 2.0 34 | r = r + 3.0 35 | r = r + 4.0 36 | r = r + 5.0 37 | r = r + 6.0 38 | r = r + 7.0 39 | r = r + 8.0 40 | r = r + 9.0 41 | r = r + 10.0 42 | r = r + 11.0 43 | r = r + 12.0 44 | r = r + 13.0 45 | r = r + 14.0 46 | r = r + 15.0 47 | r = r + 16.0 48 | r = r + 17.0 49 | r = r + 18.0 50 | r = r + 19.0 51 | r = r + 20.0 52 | r = r + 21.0 53 | r = r + 22.0 54 | r = r + 23.0 55 | r = r + 24.0 56 | r = r + 25.0 57 | end 58 | end 59 | return r 60 | end 61 | 62 | local function sum() 63 | local r = 0.0 64 | for index = 0,200,1 do 65 | for index2 = 0,500000,1 do 66 | r = r + 1.0 67 | r = r + 2.0 68 | r = r + 3.0 69 | r = r + 4.0 70 | r = r + 5.0 71 | r = r + 6.0 72 | r = r + 7.0 73 | r = r + 8.0 74 | r = r + 9.0 75 | r = r + 10.0 76 | r = r + 11.0 77 | r = r + 12.0 78 | r = r + 13.0 79 | r = r + 14.0 80 | r = r + 15.0 81 | r = r + 16.0 82 | r = r + 17.0 83 | r = r + 18.0 84 | r = r + 19.0 85 | r = r + 20.0 86 | r = r + 21.0 87 | r = r + 22.0 88 | r = r + 23.0 89 | r = r + 24.0 90 | r = r + 25.0 91 | end 92 | end 93 | return r 94 | end 95 | 96 | jit.setjitflags(sum_int, jit.JITBLACKLIST) 97 | local int_sum_start = os.clock() 98 | local int_sum_result = sum_int() 99 | local int_sum_time = os.clock() - int_sum_start 100 | assert_equal(32662565325, int_sum_result, "sum() interpreted returned the wrong value") 101 | print(string.format("sum() of int constants interpreted took %.5f", int_sum_time)) 102 | 103 | assert_compile(sum, "sum") 104 | jit.setjitflags(sum, jit.JITBLACKLIST) 105 | 106 | for i = 1,5,1 do 107 | local jit_sum_start = os.clock() 108 | local jit_sum_result = sum() 109 | local jit_sum_time = os.clock() - jit_sum_start 110 | assert_equal(32662565325, jit_sum_result, "sum() compiled returned the wrong value") 111 | print(string.format("sum() of int constants compiled took %.5f", jit_sum_time)) 112 | end 113 | -------------------------------------------------------------------------------- /test/benchmark/loop_add_double_register_with_int_constants.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | local asserts = require "asserts" 21 | local jit = require "lvjit" 22 | local assert_equal = asserts.assert_equal 23 | local assert_compile = asserts.assert_compile 24 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 25 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 26 | 27 | -- define test function 28 | local function sum_int() 29 | local r = 0.0 30 | for index = 0,200,1 do 31 | for index2 = 0,500000,1 do 32 | r = r + 1 33 | r = r + 2 34 | r = r + 3 35 | r = r + 4 36 | r = r + 5 37 | r = r + 6 38 | r = r + 7 39 | r = r + 8 40 | r = r + 9 41 | r = r + 10 42 | r = r + 11 43 | r = r + 12 44 | r = r + 13 45 | r = r + 14 46 | r = r + 15 47 | r = r + 16 48 | r = r + 17 49 | r = r + 18 50 | r = r + 19 51 | r = r + 20 52 | r = r + 21 53 | r = r + 22 54 | r = r + 23 55 | r = r + 24 56 | r = r + 25 57 | end 58 | end 59 | return r 60 | end 61 | 62 | local function sum() 63 | local r = 0.0 64 | for index = 0,200,1 do 65 | for index2 = 0,500000,1 do 66 | r = r + 1 67 | r = r + 2 68 | r = r + 3 69 | r = r + 4 70 | r = r + 5 71 | r = r + 6 72 | r = r + 7 73 | r = r + 8 74 | r = r + 9 75 | r = r + 10 76 | r = r + 11 77 | r = r + 12 78 | r = r + 13 79 | r = r + 14 80 | r = r + 15 81 | r = r + 16 82 | r = r + 17 83 | r = r + 18 84 | r = r + 19 85 | r = r + 20 86 | r = r + 21 87 | r = r + 22 88 | r = r + 23 89 | r = r + 24 90 | r = r + 25 91 | end 92 | end 93 | return r 94 | end 95 | 96 | jit.setjitflags(sum_int, jit.JITBLACKLIST) 97 | local int_sum_start = os.clock() 98 | local int_sum_result = sum_int() 99 | local int_sum_time = os.clock() - int_sum_start 100 | assert_equal(32662565325, int_sum_result, "sum() interpreted returned the wrong value") 101 | print(string.format("sum() of int constants interpreted took %.5f", int_sum_time)) 102 | 103 | assert_compile(sum, "sum") 104 | jit.setjitflags(sum, jit.JITBLACKLIST) 105 | 106 | for i = 1,5,1 do 107 | local jit_sum_start = os.clock() 108 | local jit_sum_result = sum() 109 | local jit_sum_time = os.clock() - jit_sum_start 110 | assert_equal(32662565325, jit_sum_result, "sum() compiled returned the wrong value") 111 | print(string.format("sum() of int constants compiled took %.5f", jit_sum_time)) 112 | end 113 | -------------------------------------------------------------------------------- /test/benchmark/loop_add_int_constant_with_int_register.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | local asserts = require "asserts" 21 | local jit = require "lvjit" 22 | local assert_equal = asserts.assert_equal 23 | local assert_compile = asserts.assert_compile 24 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 25 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 26 | 27 | -- define test function 28 | local function sum_int() 29 | local r = 0 30 | for index = 0,200,1 do 31 | for index2 = 0,500000,1 do 32 | r = 1 + r 33 | r = 2 + r 34 | r = 3 + r 35 | r = 4 + r 36 | r = 5 + r 37 | r = 6 + r 38 | r = 7 + r 39 | r = 8 + r 40 | r = 9 + r 41 | r = 10 + r 42 | r = 11 + r 43 | r = 12 + r 44 | r = 13 + r 45 | r = 14 + r 46 | r = 15 + r 47 | r = 16 + r 48 | r = 17 + r 49 | r = 18 + r 50 | r = 19 + r 51 | r = 20 + r 52 | r = 21 + r 53 | r = 22 + r 54 | r = 23 + r 55 | r = 24 + r 56 | r = 25 + r 57 | end 58 | end 59 | return r 60 | end 61 | 62 | local function sum() 63 | local r = 0 64 | for index = 0,200,1 do 65 | for index2 = 0,500000,1 do 66 | r = 1 + r 67 | r = 2 + r 68 | r = 3 + r 69 | r = 4 + r 70 | r = 5 + r 71 | r = 6 + r 72 | r = 7 + r 73 | r = 8 + r 74 | r = 9 + r 75 | r = 10 + r 76 | r = 11 + r 77 | r = 12 + r 78 | r = 13 + r 79 | r = 14 + r 80 | r = 15 + r 81 | r = 16 + r 82 | r = 17 + r 83 | r = 18 + r 84 | r = 19 + r 85 | r = 20 + r 86 | r = 21 + r 87 | r = 22 + r 88 | r = 23 + r 89 | r = 24 + r 90 | r = 25 + r 91 | end 92 | end 93 | return r 94 | end 95 | 96 | jit.setjitflags(sum_int, jit.JITBLACKLIST) 97 | local int_sum_start = os.clock() 98 | local int_sum_result = sum_int() 99 | local int_sum_time = os.clock() - int_sum_start 100 | assert_equal(32662565325, int_sum_result, "sum() interpreted returned the wrong value") 101 | print(string.format("sum() of int constants interpreted took %.5f", int_sum_time)) 102 | 103 | assert_compile(sum, "sum") 104 | jit.setjitflags(sum, jit.JITBLACKLIST) 105 | 106 | for i = 1,5,1 do 107 | local jit_sum_start = os.clock() 108 | local jit_sum_result = sum() 109 | local jit_sum_time = os.clock() - jit_sum_start 110 | assert_equal(32662565325, jit_sum_result, "sum() compiled returned the wrong value") 111 | print(string.format("sum() of int constants compiled took %.5f", jit_sum_time)) 112 | end 113 | -------------------------------------------------------------------------------- /test/benchmark/loop_add_int_register_with_double_constants.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | local asserts = require "asserts" 21 | local jit = require "lvjit" 22 | local assert_equal = asserts.assert_equal 23 | local assert_compile = asserts.assert_compile 24 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 25 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 26 | 27 | -- define test function 28 | local function sum_int() 29 | local r = 0 30 | for index = 0,200,1 do 31 | for index2 = 0,500000,1 do 32 | r = r + 1.0 33 | r = r + 2.0 34 | r = r + 3.0 35 | r = r + 4.0 36 | r = r + 5.0 37 | r = r + 6.0 38 | r = r + 7.0 39 | r = r + 8.0 40 | r = r + 9.0 41 | r = r + 10.0 42 | r = r + 11.0 43 | r = r + 12.0 44 | r = r + 13.0 45 | r = r + 14.0 46 | r = r + 15.0 47 | r = r + 16.0 48 | r = r + 17.0 49 | r = r + 18.0 50 | r = r + 19.0 51 | r = r + 20.0 52 | r = r + 21.0 53 | r = r + 22.0 54 | r = r + 23.0 55 | r = r + 24.0 56 | r = r + 25.0 57 | end 58 | end 59 | return r 60 | end 61 | 62 | local function sum() 63 | local r = 0 64 | for index = 0,200,1 do 65 | for index2 = 0,500000,1 do 66 | r = r + 1.0 67 | r = r + 2.0 68 | r = r + 3.0 69 | r = r + 4.0 70 | r = r + 5.0 71 | r = r + 6.0 72 | r = r + 7.0 73 | r = r + 8.0 74 | r = r + 9.0 75 | r = r + 10.0 76 | r = r + 11.0 77 | r = r + 12.0 78 | r = r + 13.0 79 | r = r + 14.0 80 | r = r + 15.0 81 | r = r + 16.0 82 | r = r + 17.0 83 | r = r + 18.0 84 | r = r + 19.0 85 | r = r + 20.0 86 | r = r + 21.0 87 | r = r + 22.0 88 | r = r + 23.0 89 | r = r + 24.0 90 | r = r + 25.0 91 | end 92 | end 93 | return r 94 | end 95 | 96 | jit.setjitflags(sum_int, jit.JITBLACKLIST) 97 | local int_sum_start = os.clock() 98 | local int_sum_result = sum_int() 99 | local int_sum_time = os.clock() - int_sum_start 100 | assert_equal(32662565325, int_sum_result, "sum() interpreted returned the wrong value") 101 | print(string.format("sum() of int constants interpreted took %.5f", int_sum_time)) 102 | 103 | assert_compile(sum, "sum") 104 | jit.setjitflags(sum, jit.JITBLACKLIST) 105 | 106 | for i = 1,5,1 do 107 | local jit_sum_start = os.clock() 108 | local jit_sum_result = sum() 109 | local jit_sum_time = os.clock() - jit_sum_start 110 | assert_equal(32662565325, jit_sum_result, "sum() compiled returned the wrong value") 111 | print(string.format("sum() of int constants compiled took %.5f", jit_sum_time)) 112 | end 113 | -------------------------------------------------------------------------------- /test/benchmark/loop_add_int_register_with_int_constants.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | local asserts = require "asserts" 21 | local jit = require "lvjit" 22 | local assert_equal = asserts.assert_equal 23 | local assert_compile = asserts.assert_compile 24 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 25 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 26 | 27 | -- define test function 28 | local function sum_int() 29 | local r = 0 30 | for index = 0,200,1 do 31 | for index2 = 0,500000,1 do 32 | r = r + 1 33 | r = r + 2 34 | r = r + 3 35 | r = r + 4 36 | r = r + 5 37 | r = r + 6 38 | r = r + 7 39 | r = r + 8 40 | r = r + 9 41 | r = r + 10 42 | r = r + 11 43 | r = r + 12 44 | r = r + 13 45 | r = r + 14 46 | r = r + 15 47 | r = r + 16 48 | r = r + 17 49 | r = r + 18 50 | r = r + 19 51 | r = r + 20 52 | r = r + 21 53 | r = r + 22 54 | r = r + 23 55 | r = r + 24 56 | r = r + 25 57 | end 58 | end 59 | return r 60 | end 61 | 62 | local function sum() 63 | local r = 0 64 | for index = 0,200,1 do 65 | for index2 = 0,500000,1 do 66 | r = r + 1 67 | r = r + 2 68 | r = r + 3 69 | r = r + 4 70 | r = r + 5 71 | r = r + 6 72 | r = r + 7 73 | r = r + 8 74 | r = r + 9 75 | r = r + 10 76 | r = r + 11 77 | r = r + 12 78 | r = r + 13 79 | r = r + 14 80 | r = r + 15 81 | r = r + 16 82 | r = r + 17 83 | r = r + 18 84 | r = r + 19 85 | r = r + 20 86 | r = r + 21 87 | r = r + 22 88 | r = r + 23 89 | r = r + 24 90 | r = r + 25 91 | end 92 | end 93 | return r 94 | end 95 | 96 | jit.setjitflags(sum_int, jit.JITBLACKLIST) 97 | local int_sum_start = os.clock() 98 | local int_sum_result = sum_int() 99 | local int_sum_time = os.clock() - int_sum_start 100 | assert_equal(32662565325, int_sum_result, "sum() interpreted returned the wrong value") 101 | print(string.format("sum() of int constants interpreted took %.5f", int_sum_time)) 102 | 103 | assert_compile(sum, "sum") 104 | jit.setjitflags(sum, jit.JITBLACKLIST) 105 | 106 | for i = 1,5,1 do 107 | local jit_sum_start = os.clock() 108 | local jit_sum_result = sum() 109 | local jit_sum_time = os.clock() - jit_sum_start 110 | assert_equal(32662565325, jit_sum_result, "sum() compiled returned the wrong value") 111 | print(string.format("sum() of int constants compiled took %.5f", jit_sum_time)) 112 | end 113 | -------------------------------------------------------------------------------- /test/control/all.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Run all test files. 22 | --]] 23 | 24 | local test_files = { "initcounter.lua" 25 | , "jitflags.lua" 26 | , "lvjitlib_compile.lua" 27 | , "jit_compile.lua" 28 | , "jit_blacklist.lua" 29 | } 30 | 31 | for _,file in ipairs(test_files) do 32 | dofile(file) 33 | end 34 | -------------------------------------------------------------------------------- /test/control/initcounter.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test if the value returned by `jit.initcallcounter()` is the documented value. 22 | ]]-- 23 | 24 | local jit = require "lvjit" 25 | 26 | assert(100 == jit.initcallcounter(), "initcallcounter different from expected value of 100") 27 | -------------------------------------------------------------------------------- /test/control/jit_blacklist.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test that a black listed function does not get JIT compiled. The test 22 | passes if the function under test is not compiled after 101 calls to it. 23 | ]]-- 24 | 25 | local jit = require "lvjit" 26 | 27 | local function foo() end 28 | 29 | assert(not jit.iscompiled(foo), "foo compiled before any calls") 30 | assert(jit.NOJITFLAGS == jit.checkjitflags(foo, -1), "default function JIT flags is not `NOJITFLAGS`") 31 | 32 | -- black list the function 33 | jit.setjitflags(foo, jit.JITBLACKLIST) 34 | assert(jit.JITBLACKLIST == jit.checkjitflags(foo, -1), "function JIT flag JITBLACKLIST not set after call to `jit.setjitflags(foo, jit.JITBLACKLIST)`") 35 | 36 | -- call `foo` enough times to force a compilation 37 | local initcount = jit.initcallcounter() 38 | for i = 1,initcount + 1 do 39 | foo() 40 | assert(not jit.iscompiled(foo), "foo compiled after "..tostring(i).." call(s) despite being black listed") 41 | end 42 | -------------------------------------------------------------------------------- /test/control/jit_compile.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test that a function gets compiled after enough calls by the interpreter. Test 22 | passes if the function under test is not compiled before and after the first 23 | 100 calls to it and the 101st call causes it to be JIT compiled. 24 | ]]-- 25 | 26 | local jit = require "lvjit" 27 | 28 | local function foo() end 29 | 30 | assert(not jit.iscompiled(foo), "foo compiled before any calls") 31 | 32 | -- call `foo` enough times to force a compilation 33 | local initcount = jit.initcallcounter() 34 | for i = 1,initcount do 35 | foo() 36 | assert(not jit.iscompiled(foo), "foo compiled after "..tostring(i).." call(s) instead of "..tostring(initcount)) 37 | end 38 | 39 | foo() 40 | assert(jit.iscompiled(foo), "foo not compiled after "..tostring(initcount).." call(s)") 41 | 42 | -------------------------------------------------------------------------------- /test/control/jitflags.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test the functions for manipulating JIT flags. The test passes if: 22 | 1) initially, a function has no JIT flags set 23 | 2) a function has a specific flag set after a call to `jit.setjitflags` sets it 24 | 3) a function has no flags set after a call to `jit.clearjitflags` clears the 25 | flag previously set 26 | ]]-- 27 | 28 | local jit = require "lvjit" 29 | 30 | local function foo() end 31 | 32 | assert(jit.NOJITFLAGS == jit.checkjitflags(foo, -1), "default function JIT flags is not `NOJITFLAGS`") 33 | jit.setjitflags(foo, jit.JITBLACKLIST) 34 | assert(jit.JITBLACKLIST == jit.checkjitflags(foo, -1), "function JIT flag JITBLACKLIST not set after call to `jit.setjitflags(foo, jit.JITBLACKLIST)`") 35 | jit.clearjitflags(foo, jit.JITBLACKLIST) 36 | assert(jit.NOJITFLAGS == jit.checkjitflags(foo, -1), "function JIT flag JITBLACKLIST set after call to `jit.clearjitflags(foo, jit.JITBLACKLIST)`") 37 | 38 | -------------------------------------------------------------------------------- /test/control/lvjitlib_compile.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test the `lvjit.compile()` function. The test passes if `foo` 22 | *is not compiled before* a call to `lvjit.compile(foo)` and 23 | *is compiled after* a call to `lvjit.compile(foo)`. 24 | ]]-- 25 | 26 | local jit = require "lvjit" 27 | 28 | local function foo() end 29 | 30 | assert(not jit.iscompiled(foo), "foo compiled before call to `jit.compile(foo)`") 31 | assert(jit.compile(foo), "foo failed to compile") 32 | assert(jit.iscompiled(foo), "foo not compiled after call to `jit.compile(foo)`") 33 | 34 | -------------------------------------------------------------------------------- /test/lvjit/.gitignore: -------------------------------------------------------------------------------- 1 | *_test 2 | -------------------------------------------------------------------------------- /test/lvjit/Makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # (c) Copyright IBM Corp. 2016, 2017 4 | # 5 | # This program and the accompanying materials are made available 6 | # under the terms of the Eclipse Public License v1.0 and 7 | # Apache License v2.0 which accompanies this distribution. 8 | # 9 | # The Eclipse Public License is available at 10 | # http://www.eclipse.org/legal/epl-v10.html 11 | # 12 | # The Apache License v2.0 is available at 13 | # http://www.opensource.org/licenses/apache2.0.php 14 | # 15 | # Contributors: 16 | # Multiple authors (IBM Corp.) - initial implementation and documentation 17 | # 18 | ################################################################################ 19 | 20 | CXX?=g++ 21 | 22 | LUA_DIR?=../../lua 23 | LVJIT_DIR?=../../lvjit 24 | JITBUILDER_DIR?=../../omr/jitbuilder/release 25 | 26 | test: compile_test initcounter_test jitflags_test 27 | ./compile_test 28 | ./initcounter_test 29 | ./jitflags_test 30 | 31 | %_test: %_test.cpp 32 | $(CXX) $< -I$(LUA_DIR) -L$(LUA_DIR) -L$(LVJIT_DIR) -L$(JITBUILDER_DIR) -llua -llvjit -ljitbuilder -ldl -o $@ 33 | 34 | clean: 35 | rm -f *_test 36 | -------------------------------------------------------------------------------- /test/lvjit/compile_test.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (c) Copyright IBM Corp. 2016, 2017 4 | * 5 | * This program and the accompanying materials are made available 6 | * under the terms of the Eclipse Public License v1.0 and 7 | * Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * Contributors: 16 | * Multiple authors (IBM Corp.) - initial implementation and documentation 17 | ******************************************************************************/ 18 | 19 | #include 20 | 21 | extern "C" { 22 | #include "lua.h" 23 | #include "luav.h" 24 | #include "lauxlib.h" 25 | #include "lualib.h" 26 | } 27 | 28 | #define SCRIPT "return 3" 29 | 30 | int main() { 31 | lua_State* L = luaL_newstate(); 32 | luaL_openlibs(L); 33 | int rc = luaL_loadstring(L, SCRIPT); 34 | assert(LUA_OK == rc); 35 | assert(!lua_iscompiled(L, -1)); 36 | lua_compile(L, -1); 37 | assert(lua_iscompiled(L, -1)); 38 | lua_call(L, 0, 1); 39 | assert(3 == lua_tointeger(L, -1)); 40 | lua_close(L); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /test/lvjit/initcounter_test.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (c) Copyright IBM Corp. 2016, 2017 4 | * 5 | * This program and the accompanying materials are made available 6 | * under the terms of the Eclipse Public License v1.0 and 7 | * Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * Contributors: 16 | * Multiple authors (IBM Corp.) - initial implementation and documentation 17 | ******************************************************************************/ 18 | 19 | #include 20 | 21 | extern "C" { 22 | #include "lua.h" 23 | #include "luav.h" 24 | #include "lauxlib.h" 25 | #include "lualib.h" 26 | } 27 | 28 | int main() { 29 | lua_State* L = luaL_newstate(); 30 | assert(100 == lua_initcallcounter(L)); 31 | lua_close(L); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /test/lvjit/jitflags_test.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (c) Copyright IBM Corp. 2016, 2017 4 | * 5 | * This program and the accompanying materials are made available 6 | * under the terms of the Eclipse Public License v1.0 and 7 | * Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * Contributors: 16 | * Multiple authors (IBM Corp.) - initial implementation and documentation 17 | ******************************************************************************/ 18 | 19 | #include 20 | 21 | extern "C" { 22 | #include "lua.h" 23 | #include "luav.h" 24 | #include "lauxlib.h" 25 | #include "lualib.h" 26 | } 27 | 28 | #define SCRIPT "return 3" 29 | 30 | int main() { 31 | lua_State* L = luaL_newstate(); 32 | int rc = luaL_loadstring(L, SCRIPT); 33 | assert(LUA_OK == rc); 34 | assert(LUA_NOJITFLAGS == lua_checkjitflags(L, -1, -1)); // check all flags 35 | lua_setjitflags(L, -1, LUA_JITBLACKLIST); 36 | assert(LUA_JITBLACKLIST == lua_checkjitflags(L, -1, -1)); 37 | lua_clearjitflags(L, -1, LUA_JITBLACKLIST); 38 | assert(LUA_NOJITFLAGS == lua_checkjitflags(L, -1, -1)); 39 | lua_close(L); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /test/opcode/all.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Run all test files 22 | 23 | Each test file is intended to a specific opcode 24 | or family of opcodes 25 | --]] 26 | 27 | local test_files = { "arithmetic.lua" 28 | , "asserts.lua" 29 | , "booleans.lua" 30 | , "call.lua" 31 | , "closure.lua" 32 | , "comparisons.lua" 33 | , "concat.lua" 34 | , "forloop.lua" 35 | , "goto.lua" 36 | , "loads.lua" 37 | , "move.lua" 38 | , "return.lua" 39 | , "self.lua" 40 | , "setlist.lua" 41 | , "tables.lua" 42 | , "tailcall.lua" 43 | , "tforloop.lua" 44 | , "upvalue.lua" 45 | , "upvaluetable.lua" 46 | , "varargs.lua" 47 | } 48 | 49 | for _,file in ipairs(test_files) do 50 | dofile(file) 51 | end 52 | -------------------------------------------------------------------------------- /test/opcode/arithmetic.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for arithmetic and bitwise opcodes 22 | 23 | Two test function are defined that exercises each arithmetic 24 | and bitwise opcode. One is compiled and used for testing, the 25 | other is used as control. The two sets of functions are in 26 | different tables. Table fields are strings that match the opcode 27 | tested by the function they map to. A test passes if the test 28 | function is successfully compiled and its returne value is the 29 | same as that of the controle (uncompiled) function when called 30 | with the same arguments. 31 | 32 | Other opcodes exercised by this function: 33 | - RETRUN 34 | --]] 35 | 36 | -- setup 37 | local asserts = require "asserts" 38 | local jit = require "lvjit" 39 | local assert_equal = asserts.assert_equal 40 | local assert_compile = asserts.assert_compile 41 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 42 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 43 | 44 | -- table of test functions 45 | local testfunc = {} 46 | testfunc.op_add = function (x, y) return x + y end 47 | testfunc.op_sub = function (x, y) return x - y end 48 | testfunc.op_mul = function (x, y) return x * y end 49 | testfunc.op_mod = function (x, y) return x % y end 50 | testfunc.op_pow = function (x, y) return x ^ y end 51 | testfunc.op_div = function (x, y) return x / y end 52 | testfunc.op_idiv = function (x, y) return x // y end 53 | testfunc.op_band = function (x, y) return x & y end 54 | testfunc.op_bor = function (x, y) return x | y end 55 | testfunc.op_bxor = function (x, y) return x ~ y end 56 | testfunc.op_shl = function (x, y) return x << y end 57 | testfunc.op_shr = function (x, y) return x >> y end 58 | testfunc.op_unm = function (x) return -x end 59 | testfunc.op_bnot = function (x) return ~x end 60 | testfunc.op_not = function (x) return not x end 61 | 62 | -- table of control functions (return expected values) 63 | local expfunc = {} 64 | expfunc.op_add = function (x, y) return x + y end 65 | expfunc.op_sub = function (x, y) return x - y end 66 | expfunc.op_mul = function (x, y) return x * y end 67 | expfunc.op_mod = function (x, y) return x % y end 68 | expfunc.op_pow = function (x, y) return x ^ y end 69 | expfunc.op_div = function (x, y) return x / y end 70 | expfunc.op_idiv = function (x, y) return x // y end 71 | expfunc.op_band = function (x, y) return x & y end 72 | expfunc.op_bor = function (x, y) return x | y end 73 | expfunc.op_bxor = function (x, y) return x ~ y end 74 | expfunc.op_shl = function (x, y) return x << y end 75 | expfunc.op_shr = function (x, y) return x >> y end 76 | expfunc.op_unm = function (x) return -x end 77 | expfunc.op_bnot = function (x) return ~x end 78 | expfunc.op_not = function (x) return not x end 79 | 80 | -- test input data 81 | local num_args = { 82 | {3, 4}, 83 | {3.3, 4}, 84 | {3, 4.4}, 85 | {3.3, 4.4}, 86 | {3, "4"}, 87 | {3.3, "4"}, 88 | {3, "4.4"}, 89 | {3.3, "4.4"}, 90 | {"3", 4}, 91 | {"3.3", 4}, 92 | {"3", 4.4}, 93 | {"3.3", 4.4}, 94 | {"3", "4"}, 95 | {"3.3", "4"}, 96 | {"3", "4.4"}, 97 | {"3.3", "4.4"} 98 | } 99 | 100 | local int_args = { 101 | {3, 4}, 102 | {3.0, 4}, 103 | {3, 4.0}, 104 | {3.0, 4.0} 105 | } 106 | 107 | -- test runner 108 | local function setup_test(opname) 109 | assert_compile(testfunc[opname], opname) 110 | jit.setjitflags(expfunc[opname], jit.BLACKLIST) 111 | assert_equal(false, jit.iscompiled(expfunc[opname]), "expected (control) "..opname.." got compiled") 112 | end 113 | 114 | local function test_runner(opname, argslist) 115 | setup_test(opname) 116 | msg = opname.."(%s:%s, %s:%s)" 117 | for _,arguments in pairs(argslist) do 118 | expected = expfunc[opname](arguments[1],arguments[2]) 119 | actual = testfunc[opname](arguments[1],arguments[2]) 120 | assert_equal(expected, actual, msg:format(arguments[1], type(arguments[1]), arguments[2], type(arguments[2]))) 121 | end 122 | end 123 | 124 | jit.setjitflags(setup_test, jit.BLACKLIST) 125 | jit.setjitflags(test_runner, jit.BLACKLIST) 126 | 127 | -- run tests 128 | test_runner("op_add", num_args) 129 | test_runner("op_sub", num_args) 130 | test_runner("op_mul", num_args) 131 | test_runner("op_mod", num_args) 132 | test_runner("op_pow", num_args) 133 | test_runner("op_div", num_args) 134 | 135 | test_runner("op_idiv", int_args) 136 | test_runner("op_band", int_args) 137 | test_runner("op_bor", int_args) 138 | test_runner("op_bxor", int_args) 139 | test_runner("op_shl", int_args) 140 | test_runner("op_shr", int_args) 141 | 142 | setup_test("op_unm") 143 | assert_equal(expfunc.op_unm(5), testfunc.op_unm(5), "op_unm(5)") 144 | assert_equal(expfunc.op_unm(3.14159), testfunc.op_unm(3.14159), "op_unm(3.14159)") 145 | 146 | setup_test("op_bnot") 147 | assert_equal(expfunc.op_bnot(15), testfunc.op_bnot(15), "op_bnot(15)") 148 | assert_equal(expfunc.op_bnot(31.0), testfunc.op_bnot(31.0), "op_bnot(31.0)") 149 | 150 | setup_test("op_not") 151 | assert_equal(expfunc.op_not(true), testfunc.op_not(true), "op_not(true)") 152 | assert_equal(expfunc.op_not(false), testfunc.op_not(false), "op_not(false)") 153 | -------------------------------------------------------------------------------- /test/opcode/asserts.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Module defining asserts that can be used 22 | in test cases 23 | --]] 24 | 25 | local jit = require "lvjit" 26 | 27 | local asserts = {} 28 | 29 | -- asserts that two values are equal 30 | asserts.assert_equal = function (exp, got, msg) 31 | assert(exp == got, msg .. " [ " .. tostring(exp) .. " ~= " .. tostring(got) .. " ]") 32 | end 33 | 34 | -- compiles a function and asserts that compilation succeeded 35 | asserts.assert_compile = function (f, info) 36 | assert(jit.compile(f), "failed to compile function "..tostring(f).." ["..info.."]") 37 | end 38 | 39 | return asserts 40 | -------------------------------------------------------------------------------- /test/opcode/booleans.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the TEST and TESTSET opcodes 22 | 23 | The TEST and TESTSET opcodes are generated when 24 | performing boolean opertations. Each test function 25 | has a boolean operation that generates a different 26 | invocation to one of the two opcodes. A test passes 27 | if the test function is successfully compiled and the 28 | value returned by the compiled function equals the 29 | expected value of the computation represented by the 30 | call to the test function. 31 | 32 | Other opcodes exercised by this function: 33 | - JMP 34 | - MOVE 35 | - RETRUN 36 | --]] 37 | 38 | -- setup 39 | local asserts = require "asserts" 40 | local jit = require "lvjit" 41 | local assert_equal = asserts.assert_equal 42 | local assert_compile = asserts.assert_compile 43 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 44 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 45 | 46 | -- define test functions 47 | local function op_and(a,b) return a and b end 48 | -- generates TESTSET with ARG_C = 0 49 | local function op_or(a,b) return a or b end 50 | -- generates TESTSET with ARG_C = 1 51 | local function ternary(a,b,c) return a and b or c end 52 | -- generates TEST and TESTSET 53 | 54 | -- run tests 55 | assert_compile(op_and, "op_and") 56 | assert_equal(false, op_and(false,false), "op_and(false,false)") 57 | assert_equal(false, op_and(false,true), "op_and(false,true)") 58 | assert_equal(false, op_and(true,false), "op_and(true,false)") 59 | assert_equal(true, op_and(true,true), "op_and(true,true)") 60 | 61 | assert_compile(op_or, "op_or") 62 | assert_equal(false, op_or(false,false), "op_or(false,false)") 63 | assert_equal(true, op_or(false,true), "op_or(false,true)") 64 | assert_equal(true, op_or(true,false), "op_or(true,false)") 65 | assert_equal(true, op_or(true,true), "op_or(true,true)") 66 | 67 | assert_compile(ternary, "ternary") 68 | assert_equal(1, ternary(true,1,2), "ternary(true,1,2)") 69 | assert_equal(2, ternary(false,1,2), "ternary(false,1,2)") 70 | -------------------------------------------------------------------------------- /test/opcode/call.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the CALL opcode 22 | 23 | Three test functions are defined. One calls a compiled Lua function, 24 | one calls a blacklisted Lua function (that must therefore be interpreted), 25 | and the last calls a C function. The first two simply return 26 | the values returned by the function they call. The last returns 27 | whether the JITBLACKLIST flag is set on the blacklisted function. 28 | A test passes if the test function is successfully compiled and 29 | the expected value is returned when the compiled test function 30 | is called. 31 | 32 | Other opcodes exercised by this function: 33 | - LOADK 34 | - GETTABUP 35 | - RETRUN 36 | --]] 37 | 38 | -- setup 39 | local asserts = require "asserts" 40 | local jit = require "lvjit" 41 | local assert_equal = asserts.assert_equal 42 | local assert_compile = asserts.assert_compile 43 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 44 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 45 | 46 | -- define test functions 47 | function getval_compiled() return 3 end -- not local to avoid generating GETUPVAL 48 | assert_compile(getval_compiled, "getval_compiled") 49 | 50 | function getval_interpreted() return 3 end -- not local to avoid generating GETUPVAL 51 | jit.setjitflags(getval_interpreted, jit.JITBLACKLIST) 52 | 53 | local function call_compiled() 54 | local r = getval_compiled() 55 | return r 56 | end 57 | 58 | local function call_interpreted() 59 | local r = getval_interpreted() 60 | return r 61 | end 62 | 63 | local function call_cfunction() 64 | local r = jit.checkjitflags(getval_interpreted, jit.JITBLACKLIST) 65 | return r 66 | end 67 | 68 | -- run tests 69 | assert_compile(call_compiled, "call_compiled") 70 | assert_equal(3, call_compiled(), "call_compiled()") 71 | 72 | assert_compile(call_interpreted, "call_interpreted") 73 | assert_equal(3, call_interpreted(), "call_interpreted()") 74 | 75 | assert_compile(call_cfunction, "call_cfunction") 76 | assert_equal(jit.JITBLACKLIST, call_cfunction(), "call_cfunction()") -------------------------------------------------------------------------------- /test/opcode/closure.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the CLOSURE opcode 22 | 23 | A test function is defined that returns another function that 24 | returns the interger value 3. The test passes if the first function 25 | is successfully compiled and the function returned by the compiled 26 | function returns 3 when called. 27 | 28 | Other opcodes exercised by this function: 29 | - RETRUN 30 | --]] 31 | 32 | -- setup 33 | local asserts = require "asserts" 34 | local jit = require "lvjit" 35 | local assert_equal = asserts.assert_equal 36 | local assert_compile = asserts.assert_compile 37 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 38 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 39 | 40 | -- define test function 41 | local op_closure = function() 42 | return function() return 3 end 43 | end 44 | 45 | -- run test 46 | assert_compile(op_closure, "op_closure") 47 | assert_equal(3, op_closure()(), "op_closure()()") 48 | -------------------------------------------------------------------------------- /test/opcode/comparisons.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test for comparison opcodes 22 | 23 | A test function is defined to exercises each compoarison 24 | opcode. The function names match the opcode they are 25 | intended to test. A test passes if the test function is 26 | successfully compiled and the value returned by the 27 | compiled function equals the expected value of the 28 | computation represented by the call to the test function. 29 | 30 | Other opcodes exercised by this function: 31 | - JMP 32 | - LOADBOOL 33 | - RETRUN 34 | --]] 35 | 36 | -- setup 37 | local asserts = require "asserts" 38 | local jit = require "lvjit" 39 | local assert_equal = asserts.assert_equal 40 | local assert_compile = asserts.assert_compile 41 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 42 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 43 | 44 | -- define test functions 45 | local function op_eq(a, b) return a == b end 46 | local function op_lt(a, b) return a < b end 47 | local function op_le(a, b) return a <= b end 48 | 49 | -- run tests 50 | assert_compile(op_eq, "op_eq") 51 | assert_equal(false, op_eq(1,2), "op_eq(1,2)") 52 | assert_equal(true, op_eq(1,1), "op_eq(1,1)") 53 | assert_equal(false, op_eq(1.0,2), "op_eq(1.0,2)") 54 | assert_equal(true, op_eq(1.0,1), "op_eq(1.0,1)") 55 | assert_equal(false, op_eq(1,2.0), "op_eq(1,2.0)") 56 | assert_equal(true, op_eq(1,1.0), "op_eq(1,1.0)") 57 | assert_equal(false, op_eq(1,1.1), "op_eq(1,1.1)") 58 | assert_equal(false, op_eq(1.0,2.0), "op_eq(1.0,2.0)") 59 | assert_equal(true, op_eq(1.0,1.0), "op_eq(1.0,1.0)") 60 | assert_equal(false, op_eq(1.0,1.1), "op_eq(1.0,1.1)") 61 | assert_equal(false, op_eq("1","2"), "op_eq('1','2')") 62 | assert_equal(true, op_eq("1","1"), "op_eq('1','1')") 63 | 64 | assert_compile(op_lt, "op_lt") 65 | assert_equal(false, op_lt(1,1), "op_lt(1,1)") 66 | assert_equal(true, op_lt(1,2), "op_lt(1,2)") 67 | assert_equal(false, op_lt(1.0,1), "op_lt(1.0,1)") 68 | assert_equal(true, op_lt(1.0,2), "op_lt(1.0,2)") 69 | assert_equal(false, op_lt(1,1.0), "op_lt(1,1.0)") 70 | assert_equal(true, op_lt(1,1.1), "op_lt(1,1.1)") 71 | assert_equal(true, op_lt(1,2.0), "op_lt(1,2.0)") 72 | assert_equal(false, op_lt(1.0,1.0), "op_lt(1.0,1.0)") 73 | assert_equal(true, op_lt(1.0,2.0), "op_lt(1.0,2.0)") 74 | assert_equal(true, op_lt(1.0,1.1), "op_lt(1.0,1.1)") 75 | assert_equal(false, op_lt("1","1"), "op_lt('1','1')") 76 | assert_equal(true, op_lt("1","2"), "op_lt('1','2')") 77 | 78 | assert_compile(op_le, "op_le") 79 | assert_equal(false, op_le(2,1), "op_le(2,1)") 80 | assert_equal(true, op_le(1,1), "op_le(1,1)") 81 | assert_equal(false, op_le(2.0,1), "op_le(2.0,1)") 82 | assert_equal(true, op_le(1.0,1), "op_le(1.0,1)") 83 | assert_equal(false, op_le(2,1.0), "op_le(2,1.0)") 84 | assert_equal(true, op_le(1,1.0), "op_le(1,1.0)") 85 | assert_equal(true, op_le(1,1.1), "op_le(1,1.1)") 86 | assert_equal(false, op_le(2.0,1.0), "op_le(2.0,1.0)") 87 | assert_equal(true, op_le(1.0,1.0), "op_le(1.0,1.0)") 88 | assert_equal(true, op_le(1.0,1.1), "op_le(1.0,1.1)") 89 | assert_equal(false, op_le("2","1"), "op_le('2','1')") 90 | assert_equal(true, op_le("1","1"), "op_le('1','1')") 91 | -------------------------------------------------------------------------------- /test/opcode/concat.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017,2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for concat opcode. 22 | 23 | Other opcodes exercised by this function: 24 | - MOVE, RETURN 25 | --]] 26 | 27 | -- setup 28 | local asserts = require "asserts" 29 | local jit = require "lvjit" 30 | local assert_equal = asserts.assert_equal 31 | local assert_compile = asserts.assert_compile 32 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 33 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 34 | 35 | local function concat2(a,b) return a .. b end 36 | local function concat3(a,b,c) return a .. b .. c end 37 | local function concat6(a,b,c,d,e,f) return a .. b .. c .. d .. e .. f end 38 | 39 | assert_compile(concat2, "concat2") 40 | jit.setjitflags(concat2, jit.BLACKLIST) 41 | assert_equal("HelloWorld", concat2("Hello", "World"), "concat2('Hello', 'World')") 42 | assert_equal("High5", concat2("High", 5), "concat2('High', 5)") 43 | assert_equal("2.0Times", concat2(2.0, "Times"), "concat2(2.0, 'Times')") 44 | 45 | assert_compile(concat3, "concat3") 46 | jit.setjitflags(concat3, jit.BLACKLIST) 47 | assert_equal("Hello World", concat3("Hello", " ", "World"), "concat2('Hello', ' ', 'World')") 48 | 49 | assert_compile(concat6, "concat6") 50 | jit.setjitflags(concat6, jit.BLACKLIST) 51 | assert_equal("The 3rd planet from the sun", concat6("The", " ", 3, "rd", " ", "planet from the sun"), "concat6('The', ' ', 3, 'rd', ' ', 'planet from the sun')") 52 | 53 | -------------------------------------------------------------------------------- /test/opcode/forloop.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test the loop opcodes 22 | 23 | A test function is defined that exercises the FORPREP 24 | and FORLOOP opcodes. A single function is used to 25 | test both of these because a well formed function 26 | cannot have one without the other. The function 27 | uses a loop to perform a computation and returns 28 | the result. The test passes if the test function is 29 | successfully compiled and a call to the compiled 30 | function returns the expected result of the 31 | computation represented by the function. 32 | 33 | Other opcodes exercised by this function: 34 | - LOADK 35 | - MOVE 36 | - AND 37 | - RETRUN 38 | --]] 39 | 40 | -- setup 41 | local asserts = require "asserts" 42 | local jit = require "lvjit" 43 | local assert_equal = asserts.assert_equal 44 | local assert_compile = asserts.assert_compile 45 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 46 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 47 | 48 | -- define test function 49 | local function sum(a,b,inc) 50 | local r = 0 51 | for i = a,b,inc do 52 | r = r + i 53 | end 54 | return r 55 | end 56 | 57 | -- run test 58 | assert_compile(sum, "sum") 59 | assert_equal(30, sum(0,10,2), "sum(0,10,2)") 60 | -------------------------------------------------------------------------------- /test/opcode/goto.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test for JMP opcode 22 | 23 | The test function defined exercises the JMP opcode. 24 | The `goto` statement generate a JMP that, when executed, 25 | will skip a variable assignment. The test passes if 26 | the test function is successfully compiled and only the 27 | first assignment to the returned variable is executed 28 | when the compiled function is called. 29 | 30 | Other opcodes exercised by this function: 31 | - LOADK 32 | - RETRUN 33 | --]] 34 | 35 | -- setup 36 | local asserts = require "asserts" 37 | local jit = require "lvjit" 38 | local assert_equal = asserts.assert_equal 39 | local assert_compile = asserts.assert_compile 40 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 41 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 42 | 43 | -- define test function 44 | local function return4not3() 45 | local a = 4 46 | goto last 47 | a = 3 48 | ::last:: 49 | return a 50 | end 51 | 52 | -- run test 53 | assert_compile(return4not3, "return4not3") 54 | assert_equal(4, return4not3(), "return4not3()") 55 | -------------------------------------------------------------------------------- /test/opcode/loads.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test the load opcodes 22 | 23 | A test function is defined that exersise the different 24 | load opcodes. Values are loaded from the constant table 25 | into registers as return values to each function. A test 26 | passes if the test function is successfully compiled and 27 | the value(s) returned by the compiled function equal the 28 | ones the function is expected to load. 29 | 30 | Other opcodes exercised by this function: 31 | - RETRUN 32 | --]] 33 | 34 | -- setup 35 | local asserts = require "asserts" 36 | local jit = require "lvjit" 37 | local assert_equal = asserts.assert_equal 38 | local assert_compile = asserts.assert_compile 39 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 40 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 41 | 42 | -- define test functions 43 | local function loadconst_3() return 3 end 44 | -- exercises LOADK 45 | local function return2vals() return 1, 2 end 46 | -- exercises LOADK (mostly to test returning more than one value) 47 | local function loadnils() local a = 1; local b,c,d; local e = 2; return a,b,c,d,e end 48 | -- exercises LOADNIL (ensures unitiailized locals get a value of nil) 49 | local function loadbool_true() return true end 50 | -- exercises LOADBOOL 51 | 52 | -- run tests 53 | assert_compile(loadconst_3, "loadconst_3") 54 | assert_equal(3, loadconst_3(), "loadconst_3()") 55 | 56 | assert_compile(return2vals, "return2vals") 57 | local a,b = return2vals() 58 | assert_equal(1, a, "first value of return2vals()") 59 | assert_equal(2, b, "second value of return2vals()") 60 | 61 | assert_compile(loadnils, "loadnils") 62 | local a,b,c,d,e = loadnils() 63 | assert_equal(1, a, "first value of loadnils()") 64 | assert_equal(nil, b, "second value of loadnils()") 65 | assert_equal(nil, c, "third value of loadnils()") 66 | assert_equal(nil, d, "fourth value of loadnils()") 67 | assert_equal(2, e, "fifth value of loadnils()") 68 | 69 | assert_compile(loadbool_true, "loadbool_true") 70 | assert_equal(true, loadbool_true(), "loadbool_true()") 71 | -------------------------------------------------------------------------------- /test/opcode/move.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test for the MOVE opcode 22 | 23 | The swap test function uses three MOVE opcodes to 24 | swap the values of its parameters. The test 25 | passes if the test function is successfully compiled 26 | and calling the compiled `swap()` on two values does not 27 | crash (good enough for now). 28 | 29 | Other opcodes exercised by this function: 30 | - RETRUN 31 | --]] 32 | 33 | -- setup 34 | local asserts = require "asserts" 35 | local jit = require "lvjit" 36 | local assert_compile = asserts.assert_compile 37 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 38 | 39 | -- define test function 40 | local function swap(a,b) a,b = b,a end 41 | 42 | -- run test 43 | assert_compile(swap, "swap") 44 | swap(3, 4) 45 | -------------------------------------------------------------------------------- /test/opcode/return.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test for RETURN opcode 22 | 23 | Each test function defined exercises RETURN in 24 | a slightly different way. `empty()` has an empty 25 | body, meaning it will only have the default 26 | RETURN that is inserted by `luac`. `justReturn()` 27 | has an explicit return statement. It will 28 | therefore have one RETURN opcode for the 29 | explicit statement, and one that is implicitly 30 | added by `luac`. A test passes if the test function 31 | is successfully compiled and the expected value 32 | is returned when calling the compiled function 33 | (`nil` if no return value is specified). 34 | --]] 35 | 36 | -- setup 37 | local asserts = require "asserts" 38 | local jit = require "lvjit" 39 | local assert_equal = asserts.assert_equal 40 | local assert_compile = asserts.assert_compile 41 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 42 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 43 | 44 | -- define test functions 45 | local function empty() end 46 | local function justReturn() return end 47 | 48 | -- run tests 49 | assert_compile(empty, "empty") 50 | assert_equal(nil, empty(), "empty()") 51 | 52 | assert_compile(justReturn, "justReturn") 53 | assert_equal(nil, justReturn(), "justReturn()") 54 | -------------------------------------------------------------------------------- /test/opcode/self.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the SELF opcode 22 | 23 | A table is defined with two fields. One field is treated as a 24 | simple variable, the other is a setter function for that variable. 25 | The test function defined takes an instance of the table, calls 26 | the setter on it using OO style (with `:`), and returns the value 27 | of the variable. The test passes if the function is successfully 28 | compiled and it returns the value given to the setter. 29 | 30 | Other opcodes exercised by this function: 31 | - LOADK 32 | - CALL 33 | - GETTABLE 34 | - RETRUN 35 | --]] 36 | 37 | -- setup 38 | local asserts = require "asserts" 39 | local jit = require "lvjit" 40 | local assert_equal = asserts.assert_equal 41 | local assert_compile = asserts.assert_compile 42 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 43 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 44 | 45 | -- define test table and function 46 | local table = {var = 0} 47 | table.setvar = function(self, v) 48 | self.var = v 49 | end 50 | 51 | local op_self = function(t, v) 52 | t:setvar(v) 53 | return t.var 54 | end 55 | 56 | -- run test 57 | assert_compile(op_self, "op_self") 58 | assert_equal(3, op_self(table, 3), "t:getvar()") 59 | -------------------------------------------------------------------------------- /test/opcode/setlist.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the CLOSURE opcode 22 | 23 | A test function is defined that returns a table constructed using 24 | a brace enclosed list. The values in the table are equal to their 25 | corresponding key. The test passes if the test function is 26 | successfully compiled and the values in the table returned by a 27 | call to the compiled function are equal to their corresponding 28 | key. 29 | 30 | Other opcodes exercised by this function: 31 | - NEWTABLE 32 | - LOADK 33 | - RETRUN 34 | --]] 35 | 36 | -- setup 37 | local asserts = require "asserts" 38 | local jit = require "lvjit" 39 | local assert_equal = asserts.assert_equal 40 | local assert_compile = asserts.assert_compile 41 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 42 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 43 | 44 | -- define test function 45 | local op_setlist = function() 46 | return {1, 2, 3, 4} 47 | end 48 | 49 | -- run test 50 | assert_compile(op_setlist, "op_setlist") 51 | table = op_setlist() 52 | for k,v in ipairs(table) do 53 | assert_equal(k,v, "checking key and value pair of table") 54 | end 55 | -------------------------------------------------------------------------------- /test/opcode/tables.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test table opcodes 22 | 23 | A test function is defined the exercises each opcode 24 | that operates on tables. The function names match 25 | the opcode they test. 26 | 27 | Other opcodes exercised by this function: 28 | - RETRUN 29 | --]] 30 | 31 | -- setup 32 | local asserts = require "asserts" 33 | local jit = require "lvjit" 34 | local assert_equal = asserts.assert_equal 35 | local assert_compile = asserts.assert_compile 36 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 37 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 38 | 39 | -- define test functions 40 | local function op_newtable() return {} end 41 | local function op_settable(t, i, v) 42 | t[i] = v 43 | end 44 | local function op_gettable(t, i) 45 | return t[i] 46 | end 47 | local function op_len(t) 48 | return #t 49 | end 50 | 51 | -- run tests 52 | 53 | -- this test passes if: 54 | -- 1) `op_newtable` is successfully compiled and 55 | -- 2) `op_gettable` is successfully compiled 56 | -- 3) `op_len` is successfully compiled and 57 | -- 4) `op_settable` is successfully compiled 58 | assert_compile(op_newtable, "op_newtable") 59 | assert_compile(op_gettable, "op_gettable") 60 | assert_compile(op_len, "op_len") 61 | assert_compile(op_settable, "op_settable") 62 | 63 | -- this test passes if: 64 | -- 1) type of returned value is `"table"` 65 | local t 66 | assert_equal("nil", type(t), "`type(t)` before op_newtable()") 67 | t = op_newtable() 68 | assert_equal("table", type(t), "`type(t)` after op_newtable()") 69 | 70 | -- this test passes if: 71 | -- 1) indexing a table element before it's assigned by `op_settable()` returns `nil` 72 | -- 2) calling `op_gettable()` before `op_settable()` is called to assign the index returns `nil` 73 | -- 3) the table length before an index is assigned by `op_settable()` is `0` 74 | -- 4) indexing a table element after it's assigned by `op_settable()` returns the assigned value 75 | -- 5) calling `op_gettable()` with an index after it's assigned by `op_settable()` returns the assigned value 76 | -- 6) the table length after an index (different thatn `1`) is assigned by `op_settable()` is `0` 77 | assert_equal(nil, t[2], "`t[2]` before op_settable(t, 2, \"two\")") 78 | assert_equal(nil, op_gettable(t, 2), "op_gettable(t, 2) before op_settable(t, 2, \"two\")") 79 | assert_equal(0, op_len(t), "op_len(t) before op_settable(t, 2, \"two\")") 80 | op_settable(t, 2, "two") 81 | assert_equal("two", t[2], "`t[2]` after op_settable(t, 2, \"two\")") 82 | assert_equal("two", op_gettable(t, 2), "op_gettable(t, 2) after op_settable(t, 2, \"two\")") 83 | assert_equal(0, op_len(t), "op_len(t) after op_settable(t, 2, \"two\")") 84 | 85 | -- this test passes if: 86 | -- 1) indexing a table element before it's assigned by `op_settable()` returns `nil` 87 | -- 2) calling `op_gettable()` before `op_settable()` is called to assign the index returns `nil` 88 | -- 3) the table length before an index is assigned by `op_settable()` is `0` 89 | -- 4) indexing a table element after `op_settable()` is called to assign it returns the assigned value 90 | -- 5) calling `op_gettable()` after `op_settable()` is calledto assign the index returns the assigned value 91 | -- 6) the table length after indexes `1` and `2` are assigned by `op_settable()` is `2` 92 | assert_equal(nil, t[1], "`t[1]` before op_settable(t, 1, \"one\")") 93 | assert_equal(nil, op_gettable(t, 1), "op_gettable(t, 1) before op_settable(t, 1, \"one\")") 94 | assert_equal(0, op_len(t), "op_len(t) before op_settable(t, 1, \"one\")") 95 | op_settable(t, 1, "one") 96 | assert_equal("one", t[1], "`t[1]` after op_settable(t, 1, \"one\")") 97 | assert_equal("one", op_gettable(t, 1), "op_gettable(t, 1) after op_settable(t, 1, \"one\")") 98 | assert_equal(2, op_len(t), "op_len(t) after op_settable(t, 1, \"one\")") 99 | -------------------------------------------------------------------------------- /test/opcode/tailcall.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the TAILCALL opcode 22 | 23 | Two test functions are defined: One tail-calls an interpreted function, 24 | the other tail-calls a compiled function. Using these three test cases 25 | are defined for: interpreter-to-JIT tail-call, JIT-to-interpreter 26 | tail-call, and JIT-to-JIT tail-call. In the first case, the test passes 27 | if the caller returns the value returned by the tail-called function. 28 | In the other two cases, the test passes if the caller is successfully 29 | compiled and calling the compiled body returns the value returned by 30 | the tail-called funcion. 31 | 32 | Other opcodes exercised by this function: 33 | - GETUPVAL 34 | - RETRUN 35 | --]] 36 | 37 | -- setup 38 | local asserts = require "asserts" 39 | local jit = require "lvjit" 40 | local assert_equal = asserts.assert_equal 41 | local assert_compile = asserts.assert_compile 42 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 43 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 44 | 45 | -- define test functions 46 | local interpreted_tail_callee = function () return 3 end 47 | jit.setjitflags(interpreted_tail_callee, jit.JITBLACKLIST) 48 | local compiled_tail_callee = function () return 3 end 49 | assert_compile(compiled_tail_callee, "compiled_tail_callee") 50 | 51 | local tailcall_interpreted = function () return interpreted_tail_callee() end 52 | local tailcall_compiled = function () return compiled_tail_callee() end 53 | 54 | -- run tests 55 | 56 | -- test interpreter-to-JIT dispatch 57 | assert_equal(3, tailcall_compiled(), "tailcall_compiled()") 58 | 59 | -- test JIT-to-interpreter dispatch 60 | assert_compile(tailcall_interpreted, "tailcall_interpreted") 61 | assert_equal(3, tailcall_interpreted(), "tailcall_interpreted()") 62 | 63 | -- test JIT-to-JIT dispatch 64 | assert_compile(tailcall_compiled, "tailcall_compiled") 65 | assert_equal(3, tailcall_compiled(), "tailcall_compiled()") 66 | -------------------------------------------------------------------------------- /test/opcode/tforloop.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for the TFORCALL and TFORLOOP opcodes 22 | 23 | A test function is defined that copies the values from one 24 | table into another. The test passes if the test function is 25 | successfully compiled and calling the compiled function on 26 | two tables results in the destenation table having the same 27 | values as the source table for all keys in the source table. 28 | 29 | Other opcodes exercised by this function: 30 | - GETTABUP 31 | - MOVE 32 | - CALL 33 | - JMP 34 | - SETTABLE 35 | - RETRUN 36 | --]] 37 | 38 | -- setup 39 | local asserts = require "asserts" 40 | local jit = require "lvjit" 41 | local assert_equal = asserts.assert_equal 42 | local assert_compile = asserts.assert_compile 43 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 44 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 45 | 46 | -- define test function 47 | local copy_into = function(dest, src) 48 | for k,v in pairs(src) do 49 | dest[k] = v 50 | end 51 | end 52 | 53 | -- run test 54 | local init_t = {1, 2, 3, 4} 55 | local other_t = {} 56 | assert_compile(copy_into, "copy_into") 57 | copy_into(other_t, init_t) 58 | for k,v in pairs(init_t) do 59 | assert_equal(other_t[k], v, "other_t[k] == v") 60 | end 61 | -------------------------------------------------------------------------------- /test/opcode/upvalue.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test upvalue opcodes 22 | 23 | A test function is defined the exercises each 24 | opcode that operates on upvalues. The 25 | test function names match the opcode they test. 26 | 27 | Other opcodes exercised by this function: 28 | - LOADK, RETRUN 29 | --]] 30 | 31 | -- setup 32 | local asserts = require "asserts" 33 | local jit = require "lvjit" 34 | local assert_equal = asserts.assert_equal 35 | local assert_compile = asserts.assert_compile 36 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 37 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 38 | 39 | -- define test functions 40 | local a 41 | local function op_setupval_a_3() a = 3 end 42 | local function op_getupval_a_3() return a end 43 | 44 | -- run tests 45 | assert_equal(nil, a, "`a` before op_setupval_a_3()") 46 | assert_compile(op_setupval_a_3, "op_setupval_a_3") 47 | op_setupval_a_3() 48 | assert_equal(3, a, "`a` after op_setupval_a_3()") 49 | 50 | assert_compile(op_getupval_a_3, "op_getupval_a_3") 51 | assert_equal(3, op_getupval_a_3(), "op_getupval_a_3()") -------------------------------------------------------------------------------- /test/opcode/upvaluetable.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2016, 2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Test upvalue table opcodes 22 | 23 | A test function is defined the exercises each 24 | opcode that operates on the upvalue table. The 25 | test function names match the opcode they test. 26 | For SETTABUP, the test passes if the test function 27 | is successfully compiled and the expected value is 28 | in the table after executing the compiled function. 29 | For GETTABUP, the test passes if the test function 30 | is successfully compiled and the value from the 31 | upvalue table is returned after executing the opcode. 32 | 33 | Other opcodes exercised by this function: 34 | - RETRUN 35 | --]] 36 | 37 | -- setup 38 | local asserts = require "asserts" 39 | local jit = require "lvjit" 40 | local assert_equal = asserts.assert_equal 41 | local assert_compile = asserts.assert_compile 42 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 43 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 44 | 45 | -- define test functions 46 | local function op_settabup_a_3() a = 3 end 47 | local function op_gettabup_a() return a end 48 | 49 | -- run tests 50 | assert_equal(nil, a, "`a` before op_settabup_a_3()") 51 | assert_compile(op_settabup_a_3, "op_settabup_a_3") 52 | op_settabup_a_3() 53 | assert_equal(3, a, "`a` after op_settabup_a_3()") 54 | 55 | assert_compile(op_gettabup_a, "op_gettabup_a") 56 | assert_equal(3, op_gettabup_a(), "op_gettabup_a()") 57 | -------------------------------------------------------------------------------- /test/opcode/varargs.lua: -------------------------------------------------------------------------------- 1 | --[[---------------------------------------------------------------------------- 2 | 3 | (c) Copyright IBM Corp. 2017,2017 4 | 5 | This program and the accompanying materials are made available 6 | under the terms of the Eclipse Public License v1.0 and 7 | Apache License v2.0 which accompanies this distribution. 8 | 9 | The Eclipse Public License is available at 10 | http://www.eclipse.org/legal/epl-v10.html 11 | 12 | The Apache License v2.0 is available at 13 | http://www.opensource.org/licenses/apache2.0.php 14 | 15 | Contributors: 16 | Multiple authors (IBM Corp.) - initial implementation and documentation 17 | 18 | --]]---------------------------------------------------------------------------- 19 | 20 | --[[ 21 | Tests for varargs opcode. 22 | 23 | Other opcodes exercised by this function: 24 | - CALL, GETTABUP, LOADK, MOVE, RETURN 25 | --]] 26 | 27 | -- setup 28 | local asserts = require "asserts" 29 | local jit = require "lvjit" 30 | local assert_equal = asserts.assert_equal 31 | local assert_compile = asserts.assert_compile 32 | jit.setjitflags(assert_equal, jit.JITBLACKLIST) 33 | jit.setjitflags(assert_compile, jit.JITBLACKLIST) 34 | 35 | local function varargs1(...) 36 | local arg1_1 = select(1,...) 37 | local arg2_1 = select(2,...) 38 | local arg1_2 = select(1,...) 39 | local arg3_1 = select(3,...) 40 | local arg2_2 = select(2,...) 41 | local arg4_1 = select(4,...) 42 | local arg_size = select("#", ...) 43 | return arg1_1,arg2_1,arg1_2,arg3_1,arg2_2,arg4_1,arg_size 44 | end 45 | 46 | assert_compile(varargs1, "varargs1") 47 | jit.setjitflags(varargs1, jit.BLACKLIST) 48 | local arg1_1,arg2_1,arg1_2,arg3_1,arg2_2,arg4_1,arg_size = varargs1(7,4,9) 49 | assert_equal(7, arg1_1, "first value of varargs1()") 50 | assert_equal(4, arg2_1, "second value of varargs1()") 51 | assert_equal(7, arg1_2, "third value of varargs1()") 52 | assert_equal(9, arg3_1, "fourth value of varargs1()") 53 | assert_equal(4, arg2_2, "fifth value of varargs1()") 54 | assert_equal(nil, arg4_1, "sixth value of varargs1()") 55 | assert_equal(3, arg_size, "seventh value of varargs1()") 56 | --------------------------------------------------------------------------------