Skip to main content

luau_vm/libs/
class.rs

1use crate::native::{NativeCallContext, NativeCallResult, NativeFunction};
2use crate::thread::Thread;
3use crate::thread::stack::RawStackAccess;
4use crate::types::LUA_TCLASS;
5
6static CLASS_LIB: [NativeFunction; 2] = [
7    NativeFunction {
8        name: "isinstance",
9        function: class_isinstance,
10    },
11    NativeFunction {
12        name: "classof",
13        function: class_classof,
14    },
15];
16
17/// `class_isinstance`
18fn class_isinstance(ctx: NativeCallContext) -> NativeCallResult {
19    let thread = ctx.raw_thread();
20    let is_instance = unsafe {
21        thread.check_any(1)?;
22        thread.check_type(2, LUA_TCLASS)?;
23
24        let instance = thread.to_object(1);
25        let object = thread.to_object(2).unwrap_unchecked();
26        let class = object.class_value();
27
28        instance.is_some_and(|instance| {
29            instance.is_object() && instance.object_value().class() == class
30        })
31    };
32
33    ctx.push_boolean(is_instance)?;
34    Ok(1)
35}
36
37/// `class_classof`
38fn class_classof(ctx: NativeCallContext) -> NativeCallResult {
39    let thread = ctx.raw_thread();
40    unsafe {
41        thread.check_any(1)?;
42
43        if thread.is_object(1) == 0 {
44            thread.push_nil()?;
45            return Ok(1);
46        }
47
48        let instance = thread.to_object(1).unwrap_unchecked().object_value();
49        let class = instance.class();
50        thread.push_class(class)?;
51        Ok(1)
52    }
53}
54
55impl Thread {
56    /// `luaopen_class`
57    pub unsafe fn open_class(&self) -> NativeCallResult {
58        unsafe { self.register(Some(super::LUA_CLASSLIB_NAME), &CLASS_LIB[..])? };
59        Ok(1)
60    }
61}