summaryrefslogtreecommitdiff
path: root/src/util.rs
diff options
context:
space:
mode:
authorkyren <kerriganw@gmail.com>2018-02-09 01:20:44 -0500
committerkyren <kerriganw@gmail.com>2018-02-09 01:22:34 -0500
commit84b009da03c9efdd353a4c9b8d9b82a997f5fa04 (patch)
tree401d70433404b99029d3a0f3422e0605282d06aa /src/util.rs
parentde4d21f8ea3606d96beabd2f95d8a814907e495d (diff)
downloadmlua-84b009da03c9efdd353a4c9b8d9b82a997f5fa04.zip
A few small performance improvements
When 'debug_assertions' is not enabled, don't bother doing asserts in stack_guard / stack_err_guard. Also, add an optional feature not enabled by default to disable LUA_USE_APICHECK in release mode. Once the bugs in rlua that allow you to trigger LUA_USE_APICHECK are fixed, this feature will be the default behavior.
Diffstat (limited to 'src/util.rs')
-rw-r--r--src/util.rs94
1 files changed, 53 insertions, 41 deletions
diff --git a/src/util.rs b/src/util.rs
index 9789d02..d8345db 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -24,25 +24,29 @@ pub unsafe fn stack_guard<F, R>(state: *mut ffi::lua_State, change: c_int, op: F
where
F: FnOnce() -> R,
{
- let expected = ffi::lua_gettop(state) + change;
- lua_internal_assert!(
- state,
- expected >= 0,
- "too many stack values would be popped"
- );
+ if cfg!(debug_assertions) {
+ let expected = ffi::lua_gettop(state) + change;
+ lua_internal_assert!(
+ state,
+ expected >= 0,
+ "too many stack values would be popped"
+ );
- let res = op();
+ let res = op();
- let top = ffi::lua_gettop(state);
- lua_internal_assert!(
- state,
- ffi::lua_gettop(state) == expected,
- "expected stack to be {}, got {}",
- expected,
- top
- );
+ let top = ffi::lua_gettop(state);
+ lua_internal_assert!(
+ state,
+ ffi::lua_gettop(state) == expected,
+ "expected stack to be {}, got {}",
+ expected,
+ top
+ );
- res
+ res
+ } else {
+ op()
+ }
}
// Run an operation on a lua_State and automatically clean up the stack before
@@ -58,37 +62,45 @@ pub unsafe fn stack_err_guard<F, R>(state: *mut ffi::lua_State, change: c_int, o
where
F: FnOnce() -> Result<R>,
{
- let expected = ffi::lua_gettop(state) + change;
- lua_internal_assert!(
- state,
- expected >= 0,
- "too many stack values would be popped"
- );
-
- let res = op();
-
- let top = ffi::lua_gettop(state);
- if res.is_ok() {
+ if cfg!(debug_assertions) {
+ let expected = ffi::lua_gettop(state) + change;
lua_internal_assert!(
state,
- ffi::lua_gettop(state) == expected,
- "expected stack to be {}, got {}",
- expected,
- top
+ expected >= 0,
+ "too many stack values would be popped"
);
+
+ let res = op();
+
+ let top = ffi::lua_gettop(state);
+ if res.is_ok() {
+ lua_internal_assert!(
+ state,
+ ffi::lua_gettop(state) == expected,
+ "expected stack to be {}, got {}",
+ expected,
+ top
+ );
+ } else {
+ lua_internal_assert!(
+ state,
+ top >= expected,
+ "{} too many stack values popped",
+ top - expected
+ );
+ if top > expected {
+ ffi::lua_settop(state, expected);
+ }
+ }
+ res
} else {
- lua_internal_assert!(
- state,
- top >= expected,
- "{} too many stack values popped",
- top - expected
- );
- if top > expected {
- ffi::lua_settop(state, expected);
+ let prev = ffi::lua_gettop(state) + change;
+ let res = op();
+ if res.is_err() {
+ ffi::lua_settop(state, prev);
}
+ res
}
-
- res
}
// Call a function that calls into the Lua API and may trigger a Lua error (longjmp) in a safe way.