LuaJIT 学习(1)—— LuaJIT介绍

news2025/3/16 1:08:21

文章目录

    • 介绍
    • Extensions Modules
      • `bit.*` — Bitwise operations
      • `ffi.*` — FFI library
      • `jit.*` — JIT compiler control
      • C API extensions
      • Profiler
    • Enhanced Standard Library Functions
      • `xpcall(f, err [,args...])` passes arguments
        • 例子: xpcall 的使用
      • `load*()` handle UTF-8 source code
        • 例子:变量名是中文
      • `load*()` add a mode parameter
      • `string.dump(f [,mode])` generates portable bytecode
      • `table.new(narray, nhash)` allocates a pre-sized table
        • 例子:table.new 的使用
      • `table.clear(tab)` clears a table
        • 例子:table.clear 的使用
      • Enhanced PRNG for `math.random()`
      • `io.*` functions handle 64 bit file offsets
      • `debug.*` functions identify metamethods
    • Fully Resumable VM
        • 例子:协程在 pcall 中 yield
        • 例子:协程在迭代器中 yield
    • Extensions from Lua 5.2
        • 例子:goto 的使用
        • 例子:'\z'转义字符的使用
        • 例子:package.loadlib 的使用
    • Extensions from Lua 5.3

介绍

LuaJIT is a Just-In-Time Compiler (JIT) for the Lua programming language. Lua is a powerful, dynamic and light-weight programming language. It may be embedded or used as a general-purpose, stand-alone language.

LuaJIT is fully upwards-compatible with Lua 5.1. It supports all standard Lua library functions and the full set of Lua/C API functions.

LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic loader level. This means you can compile a C module against the standard Lua headers and load the same shared library from either Lua or LuaJIT.

LuaJIT extends the standard Lua VM with new functionality and adds several extension modules. Please note, this page is only about functional enhancements and not about performance enhancements, such as the optimized VM, the faster interpreter or the JIT compiler.

Extensions Modules

LuaJIT comes with several built-in extension modules:

bit.* — Bitwise operations

LuaJIT supports all bitwise operations as defined by Lua BitOp:

bit.tobit  bit.tohex  bit.bnot    bit.band bit.bor  bit.bxor
bit.lshift bit.rshift bit.arshift bit.rol  bit.ror  bit.bswap

This module is a LuaJIT built-in — you don’t need to download or install Lua BitOp. The Lua BitOp site has full documentation for all Lua BitOp API functions. The FFI adds support for 64 bit bitwise operations, using the same API functions.

Please make sure to require the module before using any of its functions:

local bit = require("bit")

An already installed Lua BitOp module is ignored by LuaJIT. This way you can use bit operations from both Lua and LuaJIT on a shared installation.

ffi.* — FFI library

The FFI library allows calling external C functions and the use of C data structures from pure Lua code【重点】.

jit.* — JIT compiler control

The functions in this module control the behavior of the JIT compiler engine.

C API extensions

LuaJIT adds some extra functions to the Lua/C API.

Profiler

LuaJIT has an integrated profiler.

Enhanced Standard Library Functions

xpcall(f, err [,args...]) passes arguments

Unlike the standard implementation in Lua 5.1, xpcall() passes any arguments after the error function to the function which is called in a protected context.

例子: xpcall 的使用
local function divide(a, b)
    if b == 0 then
        error("Division by zero")
    end
    return a / b
end

local function error_handler(err)
    return "Handled error: " .. err
end

local function safe_divide(a, b)
    local status, result = xpcall(divide, error_handler, a, b)
    if status then
        return result
    else
        print("Custom Error Handler: " .. result)  -- 自定义错误处理
        return nil
    end
end

print(safe_divide(10, 2))  -- 输出:5
print(safe_divide(10, 0))  -- 输出:Custom Error Handler: Handled error: Division by zero


load*() handle UTF-8 source code

Non-ASCII characters are handled transparently by the Lua source code parser. This allows the use of UTF-8 characters in identifiers and strings. A UTF-8 BOM is skipped at the start of the source code.

例子:变量名是中文
local 姓名 = "张三"
local 年龄 = 25

print("姓名:" .. 姓名)
print("年龄:" .. 年龄)

使用标准的lua5.1会语法报错

load*() add a mode parameter

As an extension from Lua 5.2, the functions loadstring(), loadfile() and (new) load() add an optional mode parameter.

The default mode string is "bt", which allows loading of both source code and bytecode. Use "t" to allow only source code or "b" to allow only bytecode to be loaded.

By default, the load* functions generate the native bytecode format. For cross-compilation purposes, add W to the mode string to force the 32 bit format and X to force the 64 bit format. Add both to force the opposite format. 【同时使用 WX 来强制使用与本机平台相反的字节码格式】Note that non-native bytecode generated by load* cannot be run, but can still be passed to string.dump.

string.dump(f [,mode]) generates portable bytecode

An extra argument has been added to string.dump(). If set to true or to a string which contains the character s, ‘stripped’ bytecode without debug information is generated. This speeds up later bytecode loading and reduces memory usage. See also the -b command line option.

The generated bytecode is portable and can be loaded on any architecture that LuaJIT supports. However, the bytecode compatibility versions must match. Bytecode only stays compatible within a major+minor version (x.y.aaa → x.y.bbb), except for development branches. Foreign bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.

Note: LJ_GC64 mode requires a different frame layout, which implies a different, incompatible bytecode format between 32 bit and 64 bit ports. This may be rectified in the future. In the meantime, use the W and X modes of the load* functions for cross-compilation purposes.

Due to VM hardening, bytecode is not deterministic. Add d to the mode string to dump it in a deterministic manner: identical source code always gives a byte-for-byte identical bytecode dump. This feature is mainly useful for reproducible builds.

table.new(narray, nhash) allocates a pre-sized table

An extra library function table.new() can be made available via require("table.new"). This creates a pre-sized table, just like the C API equivalent lua_createtable(). This is useful for big tables if the final table size is known and automatic table resizing is too expensive.

例子:table.new 的使用
require("table.new")

t = table.new(1,1)
t[1] = 1
t["a"] = 2
print(type(t)) -- table

table.clear(tab) clears a table

An extra library function table.clear() can be made available via require("table.clear"). This clears all keys and values from a table, but preserves the allocated array/hash sizes. This is useful when a table, which is linked from multiple places, needs to be cleared and/or when recycling a table for use by the same context. This avoids managing backlinks, saves an allocation and the overhead of incremental array/hash part growth.

Please note, this function is meant for very specific situations. In most cases it’s better to replace the (usually single) link with a new table and let the GC do its wo

例子:table.clear 的使用
local tab = {1, 2, 3, a = 10, b = 20}

-- 清空表,但保留表的内存分配
require("table.clear")  -- 确保你加载了这个扩展函数
table.clear(tab)

-- 现在 tab 变成了空表,但它的内存结构(数组和哈希大小)没有改变
print(next(tab))  -- 输出 nil,因为表已经没有内容了

Enhanced PRNG for math.random()

LuaJIT uses a Tausworthe PRNG with period 2^223 to implement math.random() and math.randomseed(). The quality of the PRNG results is much superior compared to the standard Lua implementation, which uses the platform-specific ANSI rand().

The PRNG generates the same sequences from the same seeds on all platforms and makes use of all bits in the seed argument. math.random() without arguments generates 52 pseudo-random bits for every call. The result is uniformly distributed between 0.0 and 1.0. It’s correctly scaled up and rounded for math.random(n [,m]) to preserve uniformity.

Call math.randomseed() without any arguments to seed it from system entropy.

Important: Neither this nor any other PRNG based on the simplistic math.random() API is suitable for cryptographic use.

io.* functions handle 64 bit file offsets

The file I/O functions in the standard io.* library handle 64 bit file offsets. In particular, this means it’s possible to open files larger than 2 Gigabytes and to reposition or obtain the current file position for offsets beyond 2 GB (fp:seek() method).

debug.* functions identify metamethods

debug.getinfo() and lua_getinfo() also return information about invoked metamethods. The namewhat field is set to "metamethod" and the name field has the name of the corresponding metamethod (e.g. "__index").

Fully Resumable VM

The LuaJIT VM is fully resumable. This means you can yield from a coroutine even across contexts, where this would not possible with the standard Lua 5.1 VM: e.g. you can yield across pcall() and xpcall(), across iterators and across metamethods.

例子:协程在 pcall 中 yield
local function testCoroutine()
    pcall(function()
        print("Start coroutine")
        coroutine.yield() -- 在这里挂起协程
        print("Resumed coroutine")
    end)
end

local co = coroutine.create(testCoroutine)


coroutine.resume(co) -- 启动协程
coroutine.resume(co) -- 恢复协程

输出

Start coroutine
Resumed coroutine

而在标准的lua5.1中只输出

Start coroutine
例子:协程在迭代器中 yield
local coroutine = require("coroutine")

-- 一个自定义的迭代器,它会在每次返回一个元素时进行yield
function my_iterator(start, _end)
  local i = start
  return function()
    if i <= _end then
      coroutine.yield()  -- 在返回每个元素时进行yield
      i = i + 1
      return i - 1
    end
  end
end

-- 创建一个协程来使用迭代器
local co = coroutine.create(function()
  for value in my_iterator(1, 5) do
    print("迭代值: ", value)
    -- 在这里可以插入一些逻辑,例如,暂停协程,模拟某些异步操作
  end
end)

-- 在主线程中控制协程的恢复
while coroutine.status(co) ~= "dead" do
  print("恢复协程")
  coroutine.resume(co)
  -- 每次恢复时迭代器会继续从`yield`的位置往下执行
end

输出

恢复协程
恢复协程
迭代值:         1
恢复协程
迭代值:         2
恢复协程
迭代值:         3
恢复协程
迭代值:         4
恢复协程
迭代值:         5

而标准的lua5.1输出

恢复协程

Extensions from Lua 5.2

LuaJIT supports some language and library extensions from Lua 5.2. Features that are unlikely to break existing code are unconditionally enabled:

  • goto and ::labels::.
例子:goto 的使用
local i = 0

::start::  -- 标签定义

if i < 5 then
    print("i is " .. i)
    i = i + 1
    goto start  -- 跳回到 start 标签
end

print("Finished")

  • Hex escapes '\x3F' and '\z' escape in strings.

The escape sequence ‘\z’ skips the following span of white-space characters, including line breaks; it is particularly useful to break and indent a long literal string into multiple lines without adding the newlines and spaces into the string contents.

例子:'\z’转义字符的使用
local long_str ="This is a very long string that we\z
    want to break into multiple lines,\z
    but without including the newlines\z
    or spaces in the actual string content."

print(long_str)

A byte in a literal string can also be specified by its numerical value. This can be done with the escape sequence \xXX, where XX is a sequence of exactly two hexadecimal digits, or with the escape sequence \ddd, where ddd is a sequence of up to three decimal digits. (Note that if a decimal escape is to be followed by a digit, it must be expressed using exactly three digits.) Strings in Lua can contain any 8-bit value, including embedded zeros, which can be specified as ‘\0’.

  • load(string|reader [, chunkname [,mode [,env]]]).
  • loadstring() is an alias for load().
  • loadfile(filename [,mode [,env]]).
  • math.log(x [,base]).
  • string.rep(s, n [,sep]).
  • string.format(): %q reversible. %s checks __tostring. %a and "%A added.
  • String matching pattern %g added.【%g: represents all printable characters except space.】
  • io.read("*L").【\*L”: reads the next line keeping the end of line (if present), returning nil on end of file.】
  • io.lines() and file:lines() process io.read() options.【和 io.read() 函数一样的参数】
  • os.exit(status|true|false [,close]).
  • package.searchpath(name, path [, sep [, rep]]).
  • package.loadlib(name, "*").
例子:package.loadlib 的使用

假设你有两个 C 库:libcore.so 和 libext.so。libext.so 依赖于 libcore.so,但是你不想让 libcore.so 的函数直接暴露到 Lua 环境中,而是只需要确保它的符号可以在 libext.so 中使用。

-- 仅仅加载 libcore.so,并确保符号链接到 Lua 环境中
package.loadlib("libcore.so", "*")

-- 加载并使用 libext.so(它依赖于 libcore.so 的符号)
package.loadlib("libext.so", "luaopen_libext")

  • debug.getinfo() returns nparams and isvararg for option "u".
  • debug.getlocal() accepts function instead of level.
  • debug.getlocal() and debug.setlocal() accept negative indexes for varargs.
  • debug.getupvalue() and debug.setupvalue() handle C functions.
  • debug.upvalueid() and debug.upvaluejoin().
  • Lua/C API extensions: lua_version() lua_upvalueid() lua_upvaluejoin() lua_loadx() lua_copy() lua_tonumberx() lua_tointegerx() luaL_fileresult() luaL_execresult() luaL_loadfilex() luaL_loadbufferx() luaL_traceback() luaL_setfuncs() luaL_pushmodule() luaL_newlibtable() luaL_newlib() luaL_testudata() luaL_setmetatable()
  • Command line option -E.
  • Command line checks __tostring for errors.

Extensions from Lua 5.3

LuaJIT supports some extensions from Lua 5.3:

  • Unicode escape '\u{XX...}' embeds the UTF-8 encoding in string literals.【支持 Unicode 转义!】
  • The argument table arg can be read (and modified) by LUA_INIT and -e chunks.
  • io.read() and file:read() accept formats with or without a leading *.
  • assert() accepts any type of error object.
  • table.move(a1, f, e, t [,a2]).

Moves elements from table a1 to table a2, performing the equivalent to the following multiple assignment: a2[t],··· = a1[f],···,a1[e]. The default for a2 is a1. The destination range can overlap with the source range. The number of elements to be moved must fit in a Lua integer.

Returns the destination table a2.

  • coroutine.isyieldable().

Returns 1 if the given coroutine can yield, and 0 otherwise.

  • Lua/C API extensions: lua_isyieldable()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2315728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全——SpringBoot配置文件明文加密

XTHS&#xff1a;第一步、XTHS&#xff1a;第二步、XTHS&#xff1a;第三步、XTHS&#xff1a;第四步 &#xff01;就可以实现了。&#xff08;但是前提&#xff0c;你要先对你的文本进行加密&#xff0c;然后按照ENC(加密文本)&#xff0c;放到配置文件中&#xff09; 一、前言…

Docker安装Kafka(内含zookeeper)

因为kafka是基于zookeeper做的&#xff0c;所以必须要有zookeeper 一、Zookeeper 1.拉取镜像 docker pull zookeeper:3.7.02.运行 docker run --restartalways \--log-driver json-file \--log-opt max-size100m \--log-opt max-file2 \--name zookeeper -p 2181:2181 \-v…

Netty启动源码NioEventLoop剖析accept剖析read剖析write剖析

学习链接 NIO&Netty - 专栏 Netty核心技术十–Netty 核心源码剖析Netty核心技术九–TCP 粘包和拆包及解决方案Netty核心技术七–Google ProtobufNetty核心技术六–Netty核心模块组件Netty核心技术五–Netty高性能架构设计 聊聊Netty那些事儿 - 专栏 一文搞懂Netty发送数…

【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(七) -> JS动画(二)

目录 1 -> 动画动效 1.1 -> 创建动画对象 1.2 -> 添加动画事件和调用接口 2 -> 动画帧 2.1 -> 请求动画帧 2.2 -> 取消动画帧 1 -> 动画动效 通过设置插值器来实现动画效果。 说明 从API Version 6 开始支持。 1.1 -> 创建动画对象 通过cre…

LINUX下的tcp协议

TCP 1. 面向数据流&#xff08;流式套接字&#xff09; 2. 建立连接 3. 安全可靠的传输协议 应用场景&#xff1a; HTTP, MQTT, FTP 三次握手&#xff1a;TCP建立连接时&#xff0c;需要进行三次握手&#xff0c;确保收发数据前&#xff0c;双方都已准备就绪。 四次挥…

Handy Multi Agent—task1:CAMEL环境配置及你的第一个Agent

目录 1.1 获取CAMEL 1.1.1 通过 PyPI 安装 1.1.2 通过源码安装 1.1.2.1 使用 Poetry 工具从源码安装 1.1.2.2 使用Conda和Pip从源码安装 1.2.2 使用API调用模型 1.2.2.1 使用语言模型 1.2.2.2 使用多模态模型 1.2.2.3 视频理解 1.2.2.4 作业1 1.2.2.5 作业2 1.1 获取…

CSS元素层叠顺序规则

CSS元素层叠顺序规则 看图说话总结: background/borderz-index(<0)blockfloatinline/inline-blockz-index(0,auto)z-index (>0)

微服务全局ID方案汇总

自增id 对于大多数系统来说&#xff0c;使用mysql的自增id当作主键再最合适不过了。在数据库层面就可以获取一个顺序的、唯一的、空间占用少的id。 自增id需要是 int、bigint这些整数类型&#xff0c;uint 支持 40 亿的数据量&#xff0c;bigint unsign&#xff08;0 &#x…

【论文笔记】Contrastive Learning for Compact Single Image Dehazing(AECR-Net)

文章目录 问题创新网络主要贡献Autoencoder-like Dehazing NetworkAdaptive Mixup for Feature PreservingDynamic Feature Enhancement1. 可变形卷积的使用2. 扩展感受野3. 减少网格伪影4. 融合空间结构信息 Contrastive Regularization1. 核心思想2. 正样本对和负样本对的构建…

vue项目如何实现条件查询?

目录 1.前端 2.后端 3.mybatis的sql语句 结语 1.前端 说白了就是&#xff0c;无论该参数是否是空字符串&#xff0c;都会传递到后端。&#xff08;反正不是null就行&#xff09;。 2.后端 在controller层中&#xff0c;使用RequestParam注解接收名为registerName的参数&…

在Linux中安装Nginx

上传nginx安装包 Nginx的安装包&#xff0c;从官方下载下来的是c语言的源码包&#xff0c;我们需要自己编译安装。具体操作步骤如下&#xff1a; 安装nginx 安装nginx运行时需要的依赖 yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel 解压源码包到当…

【每日学点HarmonyOS Next知识】状态栏字体、生命周期、自定义对话框屏幕中间、透明度、tab居中

1、HarmonyOS 单页面如何控制状态栏字体颜色&#xff1f; 状态栏字体颜色可通过设置statusBarContentColor修改&#xff0c;参考文档如下&#xff1a; https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5 参考代码&#xff1a; import…

外贸企业可以申请网络专线吗?

在对外业务不断扩大的情况下&#xff0c;外贸企业对网络的需求愈发迫切。稳定、快速的网络连接不仅是企业开展国际业务的基础&#xff0c;更是提升竞争力的关键。外贸企业是否可以申请网络专线&#xff1f;如何选择适合的外贸网络专线服务&#xff1f;本文将为您详细解答。 网络…

阿里巴巴发布 R1-Omni:首个基于 RLVR 的全模态大语言模型,用于情感识别

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

QuickAPI 和 DBAPI 谁更香?SQL生成API工具的硬核对比(一)

最近低代码开发火得不行&#xff0c;尤其是能把数据库秒变API的工具&#xff0c;简直是开发者的救星。今天咱就聊聊两款国内玩家&#xff1a;QuickAPI&#xff08;麦聪软件搞出来的低代码神器&#xff09;和 DBAPI&#xff08;开源社区的硬核作品&#xff09;。这两货都能靠SQL…

Git使用(一)--如何在 Windows 上安装 Git:详细步骤指南

如果你想在 Windows 机器上安装 Git&#xff0c;可以按照以下详细指南进行操作。 第一步&#xff1a;下载 Git 可通过官网下载 适用于 Windows 的 Git 最新版本。 如果下载速度较慢&#xff0c;可以通过下面提供的百度网盘 链接下载安装包&#xff0c; https://git-scm.com/d…

C#-使用VisualStudio编译C#工程

一.创建csproj文件 二.创建源cs文件 三.生成解决方案 四.运行解决方案 五.VisualStudio功能列表 <1.代码格式化: CtrlKD完成代码整体格式化 <2.窗口布局 窗口->重置窗口布局 <3.引用查找&关联 <4.包管理 <5.日志输出级别 工具->选项->项目解决方案…

Qt常见面试题合集

零、基本概念 什么是信号槽? 信号槽类似于软件设计模式中的观察者模式&#xff0c;&#xff08;观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。&#xf…

vscode编译器的一些使用问题

目录 解决pip不可用问题 检查VSCode的终端配置 解决pip不可用问题 eg&#xff1a; C:\Users\student>pip pip 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 先找到系统环境变量 高级->环境变量 系统属性->Path 变量名随意&#xff0c;自己后续知道…

Docker 》》Docker Compose 》》network 网络 compose

docker 默认的网络 三种模式 # 列出所有当前主机上或Swarm集群上的网络 docker network ls#查看网络详情 docker network inspect network名称# 清除未使用的docker网络 docker network prune -f# 创建网络 ocker network create -d bridge 网络名称 docker network create –s…