luau-vm 0.732.0

Pure-Rust Luau virtual machine, garbage collector, and standard libraries
Documentation
use crate::native::{NativeCallContext, NativeCallResult, NativeFunction};
use crate::thread::Thread;
use crate::thread::stack::RawStackAccess;
use crate::types::LUA_TCLASS;

static CLASS_LIB: [NativeFunction; 2] = [
    NativeFunction {
        name: "isinstance",
        function: class_isinstance,
    },
    NativeFunction {
        name: "classof",
        function: class_classof,
    },
];

/// `class_isinstance`
fn class_isinstance(ctx: NativeCallContext) -> NativeCallResult {
    let thread = ctx.raw_thread();
    let is_instance = unsafe {
        thread.check_any(1)?;
        thread.check_type(2, LUA_TCLASS)?;

        let instance = thread.to_object(1);
        let object = thread.to_object(2).unwrap_unchecked();
        let class = object.class_value();

        instance.is_some_and(|instance| {
            instance.is_object() && instance.object_value().class() == class
        })
    };

    ctx.push_boolean(is_instance)?;
    Ok(1)
}

/// `class_classof`
fn class_classof(ctx: NativeCallContext) -> NativeCallResult {
    let thread = ctx.raw_thread();
    unsafe {
        thread.check_any(1)?;

        if thread.is_object(1) == 0 {
            thread.push_nil()?;
            return Ok(1);
        }

        let instance = thread.to_object(1).unwrap_unchecked().object_value();
        let class = instance.class();
        thread.push_class(class)?;
        Ok(1)
    }
}

impl Thread {
    /// `luaopen_class`
    pub unsafe fn open_class(&self) -> NativeCallResult {
        unsafe { self.register(Some(super::LUA_CLASSLIB_NAME), &CLASS_LIB[..])? };
        Ok(1)
    }
}