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
17fn 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
37fn 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 pub unsafe fn open_class(&self) -> NativeCallResult {
58 unsafe { self.register(Some(super::LUA_CLASSLIB_NAME), &CLASS_LIB[..])? };
59 Ok(1)
60 }
61}