Skip to main content

luaur_vm/functions/
lua_xmove.rs

1use crate::macros::api_check::api_check;
2use crate::macros::api_checknelems::api_checknelems;
3use crate::macros::blackbit::BLACKBIT;
4use crate::macros::setobj_2_s::setobj_2_s;
5use crate::type_aliases::lua_state::lua_State;
6
7#[no_mangle]
8pub unsafe fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: core::ffi::c_int) {
9    api_check!(from, n >= 0);
10
11    if from == to {
12        return;
13    }
14
15    api_checknelems!(from, n);
16    api_check!(from, (*from).global == (*to).global);
17    api_check!(from, (*(*to).ci).top.offset_from((*to).top) >= n as isize);
18
19    // Manual inline of lua_c_threadbarrier!(to) to bypass broken macros
20    let marked = (*to).hdr.marked as i32;
21    if (marked & (1 << BLACKBIT)) != 0 {
22        crate::functions::lua_c_barrierback::lua_c_barrierback(to, to as *mut _, &mut (*to).gclist);
23    }
24
25    let ttop = (*to).top;
26    let ftop = (*from).top.offset(-(n as isize));
27
28    for i in 0..n {
29        setobj_2_s!(to, ttop.offset(i as isize), ftop.offset(i as isize));
30    }
31
32    (*from).top = ftop;
33    (*to).top = ttop.offset(n as isize);
34}