Skip to content

Commit 14875d6

Browse files
committed
try compact
1 parent 5af3c09 commit 14875d6

File tree

16 files changed

+6506
-7
lines changed

16 files changed

+6506
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ members = [
55
]
66

77
[workspace.dependencies]
8-
mlua = { version = "0.10.0-beta.2", features = [ "luajit", "vendored", "async"] }
8+
mlua = { version = "0.10.0-beta.2", features = [ "luajit52", "vendored", "async"] }
99
lazy_static = "1.4.0"
1010
encoding_rs = "0.8"
1111
tokio = { version = "1.40.0", features = ["full"] }

crates/basic/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern crate lazy_static;
99
#[allow(unused)]
1010
use crate::codestyle::fake_code_style;
1111
use mlua::{lua_State, prelude::*};
12+
use override_lua::encoder;
1213

1314
extern "C-unwind" {
1415
fn luaopen_lpeglabel(lua: *mut lua_State) -> i32;
@@ -33,6 +34,10 @@ pub fn lua_preload(lua: &Lua) -> LuaResult<()> {
3334
add_preload_module(&lua, "code_format", code_format_loader)?;
3435
}
3536

37+
utf8::register_lua_utf8(lua)?;
38+
let encoder_loader = lua.create_function(|lua: &Lua, ()| Ok(encoder::lua_encoder_loader(lua)))?;
39+
add_preload_module(&lua, "encoder", encoder_loader)?;
40+
3641
// bee.platform
3742
let bee_platform_loader =
3843
lua.create_function(|lua: &Lua, ()| Ok(bee::lua_platform::bee_platform(lua)))?;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use mlua::{ffi::lua, lua_State, prelude::*};
2+
use std::cmp;
3+
4+
enum EncoderEncoding {
5+
UTF8,
6+
UTF16,
7+
UTF16LE,
8+
UTF16BE,
9+
}
10+
11+
enum EncoderBom {
12+
No,
13+
Yes,
14+
Auto,
15+
}
16+
17+
fn get_encoder_encoding(encoding: &str) -> Option<EncoderEncoding> {
18+
match encoding {
19+
"utf8" => Some(EncoderEncoding::UTF8),
20+
"utf16" => Some(EncoderEncoding::UTF16),
21+
"utf16le" => Some(EncoderEncoding::UTF16LE),
22+
"utf16be" => Some(EncoderEncoding::UTF16BE),
23+
_ => None,
24+
}
25+
}
26+
27+
fn get_encoder_bom(bom: &str) -> Option<EncoderBom> {
28+
match bom {
29+
"no" => Some(EncoderBom::No),
30+
"yes" => Some(EncoderBom::Yes),
31+
"auto" => Some(EncoderBom::Auto),
32+
_ => None,
33+
}
34+
}
35+
36+
fn encoder_len(lua: &Lua, (encoding, s, i, j): (String, String, Option<i32>, Option<i32>)) -> LuaResult<i32> {
37+
let len = s.len() as i32;
38+
39+
let start = match i {
40+
Some(idx) if idx > 0 => cmp::min(idx - 1, len),
41+
Some(idx) if idx < 0 => cmp::max(len + idx, 0),
42+
_ => 0,
43+
};
44+
45+
let end = match j {
46+
Some(idx) if idx > 0 => cmp::min(idx, len),
47+
Some(idx) if idx < 0 => cmp::max(len + idx + 1, 0),
48+
_ => len,
49+
};
50+
51+
let substr = &s[start as usize..end as usize];
52+
53+
match get_encoder_encoding(&encoding) {
54+
Some(EncoderEncoding::UTF8) => Ok(substr.len() as i32),
55+
Some(EncoderEncoding::UTF16) | Some(EncoderEncoding::UTF16LE) | Some(EncoderEncoding::UTF16BE) => {
56+
Ok(substr.encode_utf16().count() as i32)
57+
}
58+
None => Err(mlua::Error::RuntimeError("Unsupported encoding".to_string())),
59+
}
60+
}
61+
62+
fn encoder_offset(lua: &Lua, (encoding, s, n, i): (String, String, i32, Option<i32>)) -> LuaResult<i32> {
63+
let len = s.len() as i32;
64+
65+
let start = match i {
66+
Some(idx) if idx > 0 => cmp::min(idx - 1, len),
67+
Some(idx) if idx < 0 => cmp::max(len + idx, 0),
68+
_ => 0,
69+
};
70+
71+
let substr = &s[start as usize..];
72+
73+
let mut char_count = 0;
74+
for (byte_idx, _) in substr.char_indices() {
75+
if char_count == n {
76+
return Ok((start + byte_idx as i32) as i32);
77+
}
78+
char_count += 1;
79+
}
80+
81+
Ok(-1)
82+
}
83+
84+
fn encoder_encode(lua: &Lua, (encoding, s, bom): (String, String, String)) -> LuaResult<String> {
85+
let bom = get_encoder_bom(&bom).ok_or_else(|| mlua::Error::RuntimeError("Invalid BOM option".to_string()))?;
86+
let encoding = get_encoder_encoding(&encoding).ok_or_else(|| mlua::Error::RuntimeError("Unsupported encoding".to_string()))?;
87+
88+
let mut encoded: Vec<u8> = match encoding {
89+
EncoderEncoding::UTF8 => s.into_bytes(),
90+
EncoderEncoding::UTF16 | EncoderEncoding::UTF16LE => s.encode_utf16().flat_map(|u| u.to_le_bytes()).collect(),
91+
EncoderEncoding::UTF16BE => s.encode_utf16().flat_map(|u| u.to_be_bytes()).collect(),
92+
};
93+
94+
if let EncoderBom::Yes = bom {
95+
match encoding {
96+
EncoderEncoding::UTF8 => encoded.splice(0..0, [0xEF, 0xBB, 0xBF].iter().cloned()).for_each(drop),
97+
EncoderEncoding::UTF16 | EncoderEncoding::UTF16LE => encoded.splice(0..0, [0xFF, 0xFE].iter().cloned()).for_each(drop),
98+
EncoderEncoding::UTF16BE => encoded.splice(0..0, [0xFE, 0xFF].iter().cloned()).for_each(drop),
99+
}
100+
}
101+
102+
Ok(encoded.iter().map(|b| *b as char).collect())
103+
}
104+
105+
fn encoder_decode(lua: &Lua, (encoding, s): (String, String)) -> LuaResult<String> {
106+
let encoding = get_encoder_encoding(&encoding).ok_or_else(|| mlua::Error::RuntimeError("Unsupported encoding".to_string()))?;
107+
108+
let decoded = match encoding {
109+
EncoderEncoding::UTF8 => s,
110+
EncoderEncoding::UTF16 | EncoderEncoding::UTF16LE => {
111+
let bytes: Vec<u16> = s.as_bytes().chunks(2).map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]])).collect();
112+
String::from_utf16(&bytes).map_err(|e| mlua::Error::RuntimeError(e.to_string()))?
113+
}
114+
EncoderEncoding::UTF16BE => {
115+
let bytes: Vec<u16> = s.as_bytes().chunks(2).map(|chunk| u16::from_be_bytes([chunk[0], chunk[1]])).collect();
116+
String::from_utf16(&bytes).map_err(|e| mlua::Error::RuntimeError(e.to_string()))?
117+
}
118+
};
119+
120+
Ok(decoded)
121+
}
122+
123+
pub fn lua_encoder_loader(lua: &Lua) -> LuaResult<LuaTable> {
124+
let encoder = lua.create_table()?;
125+
encoder.set("len", lua.create_function(encoder_len)?);
126+
encoder.set("offset", lua.create_function(encoder_offset)?);
127+
encoder.set("encode", lua.create_function(encoder_encode)?);
128+
encoder.set("decode", lua.create_function(encoder_decode)?);
129+
Ok(encoder)
130+
}

crates/basic/src/override_lua/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod encoder;

crates/basic/src/utf8/mod.rs

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,131 @@
1-
use mlua::{ffi, lua_State, prelude::*, Lua};
1+
use mlua::{prelude::*, Lua, Value};
2+
use std::cmp;
23

4+
fn lua_utf8_len(
5+
lua: &Lua,
6+
(s, i, j, lax): (String, Option<i32>, Option<i32>, Option<bool>),
7+
) -> LuaResult<i32> {
8+
let len = s.len() as i32;
39

4-
// compact for luajit
5-
pub fn register_lua_utf8(lua: &Lua) -> LuaResult<()> {
10+
let start = match i {
11+
Some(idx) if idx > 0 => cmp::min(idx - 1, len), // start from 1
12+
Some(idx) if idx < 0 => cmp::max(len + idx, 0),
13+
_ => 0,
14+
};
15+
16+
let end = match j {
17+
Some(idx) if idx > 0 => cmp::min(idx, len),
18+
Some(idx) if idx < 0 => cmp::max(len + idx + 1, 0),
19+
_ => len,
20+
};
21+
22+
let substr = &s[start as usize..end as usize];
23+
24+
Ok(if lax.unwrap_or(false) {
25+
substr.chars().count() as i32
26+
} else {
27+
match substr.chars().count() {
28+
count => count as i32,
29+
}
30+
})
31+
}
32+
33+
// Receives zero or more integers, converts each one to its corresponding UTF-8 byte sequence and returns a string with the concatenation of all these sequences.
34+
fn lua_utf8_char(lua: &Lua, args: mlua::MultiValue) -> LuaResult<String> {
35+
let mut result = String::new();
36+
37+
for arg in args {
38+
match arg {
39+
Value::Integer(i) => {
40+
if let Some(c) = std::char::from_u32(i as u32) {
41+
result.push(c);
42+
}
43+
}
44+
_ => {}
45+
}
46+
}
47+
48+
Ok(result)
49+
}
50+
51+
// Returns the codepoints (as integers) from all characters in `s` that start between byte position `i` and `j` (both included).
52+
fn lua_utf8_codepoint(
53+
lua: &Lua,
54+
(s, i, j, lax): (String, Option<i32>, Option<i32>, Option<bool>),
55+
) -> LuaResult<mlua::MultiValue> {
56+
let len = s.len() as i32;
57+
58+
let start = match i {
59+
Some(idx) if idx > 0 => cmp::min(idx - 1, len),
60+
Some(idx) if idx < 0 => cmp::max(len + idx, 0),
61+
_ => 0,
62+
};
63+
64+
let end = match j {
65+
Some(idx) if idx > 0 => cmp::min(idx, len),
66+
Some(idx) if idx < 0 => cmp::max(len + idx + 1, 0),
67+
_ => len,
68+
};
69+
70+
let substr = &s[start as usize..end as usize];
71+
let mut result = mlua::MultiValue::new();
672

73+
for c in substr.chars() {
74+
if lax.unwrap_or(false) {
75+
if let Some(codepoint) = c.to_digit(10) {
76+
result.push_back(Value::Integer(codepoint as i64));
77+
}
78+
} else {
79+
result.push_back(Value::Integer(c as u32 as i64));
80+
}
81+
}
782

83+
Ok(result)
84+
}
85+
86+
// Returns the position (in bytes) where the encoding of the `n`-th character of `s` (counting from position `i`) starts.
87+
fn lua_utf8_offset(lua: &Lua, (s, n, i): (String, i32, Option<i32>)) -> LuaResult<i32> {
88+
let len = s.len() as i32;
89+
90+
let start = match i {
91+
Some(idx) if idx > 0 => cmp::min(idx - 1, len),
92+
Some(idx) if idx < 0 => cmp::max(len + idx, 0),
93+
_ => 0,
94+
};
95+
96+
let substr = &s[start as usize..];
97+
98+
let mut char_count = 0;
99+
for (byte_idx, _) in substr.char_indices() {
100+
if char_count == n {
101+
return Ok((start + byte_idx as i32) as i32);
102+
}
103+
char_count += 1;
104+
}
105+
106+
Ok(-1)
107+
}
108+
109+
110+
// fn lua_utf8_codes(lua: &Lua, s: String) -> LuaResult<(mlua::Function, mlua::Table, mlua::Value)> {
111+
// let mut table = lua.create_table()?;
112+
113+
// for c in s.chars() {
114+
// table.push_back(Value::Integer(c as u32 as i64));
115+
// }
116+
117+
// let next = lua.globals().get("next")?;
118+
// oK((next, table, Value::Nil))
119+
// }
120+
121+
// compact for luajit
122+
pub fn register_lua_utf8(lua: &Lua) -> LuaResult<()> {
123+
let utf8 = lua.create_table()?;
124+
utf8.set("len", lua.create_function(lua_utf8_len)?)?;
125+
utf8.set("char", lua.create_function(lua_utf8_char)?)?;
126+
utf8.set("codepoint", lua.create_function(lua_utf8_codepoint)?)?;
127+
utf8.set("offset", lua.create_function(lua_utf8_offset)?)?;
128+
// utf8.set("codes", lua.create_function(lua_utf8_codes)?)?;
129+
lua.globals().set("utf8", utf8)?;
8130
Ok(())
9131
}

resources/luajitCompact.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
table.unpack = unpack
2+
3+
table.pack = function(...)
4+
return { n = select('#', ...), ... }
5+
end

resources/main.lua

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require "luajitCompact"
12
local fs = require 'bee.filesystem'
23
local util = require 'utility'
34
local version = require 'version'
@@ -53,9 +54,10 @@ ROOT = fs.absolute(util.expandPath(rootPath))
5354
LOGPATH = LOGPATH and util.expandPath(LOGPATH) or (ROOT:string() .. '/log')
5455
METAPATH = METAPATH and util.expandPath(METAPATH) or (ROOT:string() .. '/meta')
5556

57+
5658
---@diagnostic disable-next-line: deprecated
57-
debug.setcstacklimit(200)
58-
collectgarbage('generational', 10, 50)
59+
-- debug.setcstacklimit(200)
60+
-- collectgarbage('generational', 10, 50)
5961
--collectgarbage('incremental', 120, 120, 0)
6062

6163
---@diagnostic disable-next-line: lowercase-global
@@ -77,6 +79,7 @@ xpcall(dofile, log.debug, (ROOT / 'debugger.lua'):string())
7779

7880
require 'cli'
7981

80-
local _, service = xpcall(require, log.error, 'service')
82+
-- local _, service = xpcall(require, log.error, 'service')
83+
local service = require 'service'
8184

8285
service.start()

0 commit comments

Comments
 (0)