Add `push_array{,2}()`

This commit is contained in:
wtfsck 2022-05-18 21:06:07 +02:00
parent d0e7d0ee4c
commit 0cbf0c2c01
3 changed files with 44 additions and 20 deletions

View File

@ -1323,14 +1323,7 @@ lua_pub_methods! { static INSTRUCTION_EXPORTS =>
/// ```
unsafe fn cpuid_features(lua, instr: &Instruction) -> 1 {
let cpuid_features = instr.inner.cpuid_features();
unsafe {
lua.create_table(cpuid_features.len() as c_int, 0);
for (i, &cpuid) in cpuid_features.iter().enumerate() {
lua.push(i + 1);
lua.push(cpuid as u32);
lua.raw_set(-3);
}
}
unsafe { lua.push_array(cpuid_features, |_, cpuid| *cpuid as u32); }
}
/// Control flow info (a `FlowControl` enum value)

View File

@ -2,7 +2,6 @@
// Copyright (C) 2018-present iced project and contributors
use crate::enum_utils::to_code;
use libc::c_int;
use loona::lua_api::lua_CFunction;
use loona::prelude::*;
@ -852,15 +851,8 @@ lua_pub_methods! { static OP_CODE_INFO_EXPORTS =>
/// Gets all operand kinds (a list of `OpCodeOperandKind` enum values)
/// @returns integer[] # (`OpCodeOperandKind[]`) All operand kinds
unsafe fn op_kinds(lua, opci: &OpCodeInfo) -> 1 {
unsafe {
let op_kinds = opci.inner.op_kinds();
lua.create_table(op_kinds.len() as c_int, 0);
for (i, &op_kind) in op_kinds.iter().enumerate() {
lua.push(i + 1);
lua.push(op_kind as u32);
lua.raw_set(-3);
}
}
let op_kinds = opci.inner.op_kinds();
unsafe { lua.push_array(op_kinds, |_, op_kind| *op_kind as u32); }
}
/// Checks if the instruction is available in 16-bit mode, 32-bit mode or 64-bit mode

View File

@ -825,9 +825,9 @@ impl<'lua> Lua<'lua> {
/// the Lua stack and then `read_elem()` is called. The callee should return the Rust value
/// but not pop the Lua stack.
#[inline]
pub unsafe fn read_array<T, F, E: Error>(&self, idx: c_int, read_elem: F) -> Vec<T>
pub unsafe fn read_array<T, F, E: Error>(&self, idx: c_int, mut read_elem: F) -> Vec<T>
where
F: Fn(&Self) -> Result<T, E>,
F: FnMut(&Self) -> Result<T, E>,
{
unsafe {
if !self.is_table(idx) {
@ -859,6 +859,45 @@ impl<'lua> Lua<'lua> {
result
}
}
/// Creates a new array and pushes it onto the Lua stack and initializes it with the input array
#[inline]
pub unsafe fn push_array<T, TNew: ToLua, F>(&self, elems: &[T], mut convert: F)
where
F: FnMut(&Self, &T) -> TNew,
{
unsafe {
self.create_table(elems.len() as c_int, 0);
for (i, value) in elems.iter().enumerate() {
let new_value = convert(self, value);
self.push(i + 1);
self.push(new_value);
self.raw_set(-3);
}
}
}
/// Creates a new array and pushes it onto the Lua stack and initializes it with the input array
#[inline]
pub unsafe fn push_array2<T, F>(&self, elems: &[T], mut push_value: F)
where
F: FnMut(&Self, &T),
{
unsafe {
self.create_table(elems.len() as c_int, 0);
for (i, value) in elems.iter().enumerate() {
self.push(i + 1);
#[cfg(any(debug_assertions, feature = "extra_checks"))]
let _orig_top = self.get_top();
push_value(self, value);
#[cfg(any(debug_assertions, feature = "extra_checks"))]
assert_eq!(1, self.get_top().wrapping_sub(_orig_top));
self.raw_set(-3);
}
}
}
}
// Simple wrappers calling the Lua C API