Skip to main content

luaur_vm/functions/
lua_v_equalval.rs

1use crate::enums::lua_type::lua_Type;
2use crate::functions::call_t_mres::call_t_mres;
3use crate::functions::get_comp_tm::get_comp_tm;
4use crate::functions::lua_t_gettmbyobj::lua_t_gettmbyobj;
5use crate::functions::luai_veceq::luai_veceq;
6use crate::macros::bvalue::bvalue;
7use crate::macros::classvalue::classvalue;
8use crate::macros::gcvalue::gcvalue;
9use crate::macros::hvalue::hvalue;
10use crate::macros::l_isfalse::l_isfalse;
11use crate::macros::lightuserdatatag::lightuserdatatag;
12use crate::macros::luai_inteq::luai_inteq;
13use crate::macros::luai_numeq::luai_numeq;
14use crate::macros::lvalue::lvalue;
15use crate::macros::nvalue::nvalue;
16use crate::macros::objectvalue::objectvalue;
17use crate::macros::ttisnil::ttisnil;
18use crate::macros::ttype::ttype;
19use crate::macros::uvalue::uvalue;
20use crate::macros::vvalue::vvalue;
21use crate::type_aliases::lua_state::LuaState;
22use crate::type_aliases::t_value::TValue;
23use crate::type_aliases::tms::TMS;
24use luaur_common::macros::luau_assert::LUAU_ASSERT;
25
26#[allow(non_snake_case)]
27pub unsafe fn lua_v_equalval(L: *mut LuaState, t1: *const TValue, t2: *const TValue) -> i32 {
28    let tm: *const TValue;
29    LUAU_ASSERT!(ttype!(t1) == ttype!(t2));
30
31    match ttype!(t1) {
32        t if t == lua_Type::LUA_TNIL as i32 => return 1,
33        t if t == lua_Type::LUA_TNUMBER as i32 => {
34            return if luai_numeq(nvalue!(t1), nvalue!(t2)) {
35                1
36            } else {
37                0
38            };
39        }
40        t if t == lua_Type::LUA_TINTEGER as i32 => {
41            return if luai_inteq(lvalue!(t1) as f64, lvalue!(t2) as f64) {
42                1
43            } else {
44                0
45            };
46        }
47        t if t == lua_Type::LUA_TVECTOR as i32 => {
48            return if luai_veceq(vvalue!(t1).as_ptr(), vvalue!(t2).as_ptr()) {
49                1
50            } else {
51                0
52            };
53        }
54        t if t == lua_Type::LUA_TBOOLEAN as i32 => {
55            return if bvalue!(t1) == bvalue!(t2) { 1 } else { 0 };
56        }
57        t if t == lua_Type::LUA_TLIGHTUSERDATA as i32 => {
58            return if ((*t1).value.p == (*t2).value.p)
59                && (lightuserdatatag!(t1) == lightuserdatatag!(t2))
60            {
61                1
62            } else {
63                0
64            };
65        }
66        t if t == lua_Type::LUA_TUSERDATA as i32 => {
67            let u1 = uvalue!(t1);
68            let u2 = uvalue!(t2);
69            tm = get_comp_tm(L, (*u1).metatable, (*u2).metatable, TMS::TM_EQ);
70            if tm.is_null() {
71                return if core::ptr::eq(u1, u2) { 1 } else { 0 };
72            }
73        }
74        t if t == lua_Type::LUA_TCLASS as i32 => {
75            return if core::ptr::eq(classvalue!(t1), classvalue!(t2)) {
76                1
77            } else {
78                0
79            };
80        }
81        t if t == lua_Type::LUA_TOBJECT as i32 => {
82            let t1inst = objectvalue!(t1);
83            let t2inst = objectvalue!(t2);
84            if (*t1inst).lclass != (*t2inst).lclass {
85                return 0;
86            }
87            tm = lua_t_gettmbyobj(L, t1, TMS::TM_EQ);
88            if ttisnil!(tm) {
89                return if core::ptr::eq(t1inst, t2inst) { 1 } else { 0 };
90            }
91        }
92        t if t == lua_Type::LUA_TTABLE as i32 => {
93            let h1 = hvalue!(t1);
94            let h2 = hvalue!(t2);
95            tm = get_comp_tm(L, (*h1).metatable, (*h2).metatable, TMS::TM_EQ);
96            if tm.is_null() {
97                return if core::ptr::eq(h1, h2) { 1 } else { 0 };
98            }
99        }
100        _ => {
101            return if core::ptr::eq(gcvalue!(t1), gcvalue!(t2)) {
102                1
103            } else {
104                0
105            };
106        }
107    }
108
109    call_t_mres(L, (*L).top, tm, t1, t2);
110    if !l_isfalse!((*L).top) {
111        1
112    } else {
113        0
114    }
115}
116
117#[export_name = "luaV_equalval"]
118pub unsafe extern "C" fn lua_v_equalval_export(
119    L: *mut LuaState,
120    t1: *const TValue,
121    t2: *const TValue,
122) -> i32 {
123    lua_v_equalval(L, t1, t2)
124}