Skip to content

Commit ec227f9

Browse files
committed
Optimize Table readonly check (Luau)
Optimize `Table::has_metatable` check.
1 parent 93a1a55 commit ec227f9

File tree

1 file changed

+20
-27
lines changed

1 file changed

+20
-27
lines changed

src/table.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::function::Function;
99
use crate::state::{LuaGuard, RawLua};
1010
use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike};
1111
use crate::types::{Integer, LuaType, ValueRef};
12-
use crate::util::{assert_stack, check_stack, StackGuard};
12+
use crate::util::{assert_stack, check_stack, get_metatable_ptr, StackGuard};
1313
use crate::value::{Nil, Value};
1414

1515
#[cfg(feature = "async")]
@@ -242,12 +242,12 @@ impl Table {
242242

243243
/// Sets a key-value pair without invoking metamethods.
244244
pub fn raw_set(&self, key: impl IntoLua, value: impl IntoLua) -> Result<()> {
245-
#[cfg(feature = "luau")]
246-
self.check_readonly_write()?;
247-
248245
let lua = self.0.lua.lock();
249246
let state = lua.state();
250247
unsafe {
248+
#[cfg(feature = "luau")]
249+
self.check_readonly_write(&lua)?;
250+
251251
let _sg = StackGuard::new(state);
252252
check_stack(state, 5)?;
253253

@@ -312,12 +312,12 @@ impl Table {
312312

313313
/// Appends a value to the back of the table without invoking metamethods.
314314
pub fn raw_push(&self, value: impl IntoLua) -> Result<()> {
315-
#[cfg(feature = "luau")]
316-
self.check_readonly_write()?;
317-
318315
let lua = self.0.lua.lock();
319316
let state = lua.state();
320317
unsafe {
318+
#[cfg(feature = "luau")]
319+
self.check_readonly_write(&lua)?;
320+
321321
let _sg = StackGuard::new(state);
322322
check_stack(state, 4)?;
323323

@@ -340,12 +340,12 @@ impl Table {
340340

341341
/// Removes the last element from the table and returns it, without invoking metamethods.
342342
pub fn raw_pop<V: FromLua>(&self) -> Result<V> {
343-
#[cfg(feature = "luau")]
344-
self.check_readonly_write()?;
345-
346343
let lua = self.0.lua.lock();
347344
let state = lua.state();
348345
unsafe {
346+
#[cfg(feature = "luau")]
347+
self.check_readonly_write(&lua)?;
348+
349349
let _sg = StackGuard::new(state);
350350
check_stack(state, 3)?;
351351

@@ -401,13 +401,13 @@ impl Table {
401401
///
402402
/// This method is useful to clear the table while keeping its capacity.
403403
pub fn clear(&self) -> Result<()> {
404-
#[cfg(feature = "luau")]
405-
self.check_readonly_write()?;
406-
407404
let lua = self.0.lua.lock();
408405
unsafe {
409406
#[cfg(feature = "luau")]
410-
ffi::lua_cleartable(lua.ref_thread(), self.0.index);
407+
{
408+
self.check_readonly_write(&lua)?;
409+
ffi::lua_cleartable(lua.ref_thread(), self.0.index);
410+
}
411411

412412
#[cfg(not(feature = "luau"))]
413413
{
@@ -550,14 +550,7 @@ impl Table {
550550
#[inline]
551551
pub fn has_metatable(&self) -> bool {
552552
let lua = self.0.lua.lock();
553-
let ref_thread = lua.ref_thread();
554-
unsafe {
555-
if ffi::lua_getmetatable(ref_thread, self.0.index) != 0 {
556-
ffi::lua_pop(ref_thread, 1);
557-
return true;
558-
}
559-
}
560-
false
553+
unsafe { !get_metatable_ptr(lua.ref_thread(), self.0.index).is_null() }
561554
}
562555

563556
/// Sets `readonly` attribute on the table.
@@ -724,12 +717,12 @@ impl Table {
724717
/// Sets element value at position `idx` without invoking metamethods.
725718
#[doc(hidden)]
726719
pub fn raw_seti(&self, idx: usize, value: impl IntoLua) -> Result<()> {
727-
#[cfg(feature = "luau")]
728-
self.check_readonly_write()?;
729-
730720
let lua = self.0.lua.lock();
731721
let state = lua.state();
732722
unsafe {
723+
#[cfg(feature = "luau")]
724+
self.check_readonly_write(&lua)?;
725+
733726
let _sg = StackGuard::new(state);
734727
check_stack(state, 5)?;
735728

@@ -765,8 +758,8 @@ impl Table {
765758

766759
#[cfg(feature = "luau")]
767760
#[inline(always)]
768-
pub(crate) fn check_readonly_write(&self) -> Result<()> {
769-
if self.is_readonly() {
761+
fn check_readonly_write(&self, lua: &RawLua) -> Result<()> {
762+
if unsafe { ffi::lua_getreadonly(lua.ref_thread(), self.0.index) != 0 } {
770763
return Err(Error::runtime("attempt to modify a readonly table"));
771764
}
772765
Ok(())

0 commit comments

Comments
 (0)