roblox_emulator: fix subtle ustr bugs

This commit is contained in:
Quaternions 2025-04-22 13:38:11 -07:00
parent fa07d16cf4
commit 08b5445838
Signed by: Quaternions
GPG Key ID: D0DF5964F79AC131

@ -219,22 +219,23 @@ impl mlua::UserData for Instance{
});
methods.add_meta_function(mlua::MetaMethod::Index,|lua,(this,index):(Instance,mlua::String)|{
let index_str=&*index.to_str()?;
let Some(index_ustr)=Ustr::from_existing(index_str)else{
return Ok(mlua::Value::Nil)
};
dom_mut(lua,|dom|{
let instance=this.get(dom)?;
//println!("__index t={} i={index:?}",instance.name);
let db=rbx_reflection_database::get();
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
//Find existing property
match instance.properties.get(&index_ustr)
.cloned()
// Find existing property
// Interestingly, ustr can know ahead of time if
// a property does not exist in any runtime instance
match Ustr::from_existing(index_str)
.and_then(|index_ustr|
instance.properties.get(&index_ustr).cloned()
)
//Find default value
.or_else(||db.find_default_property(class,index_str).cloned())
//Find virtual property
.or_else(||db.superclasses_iter(class).find_map(|class|
find_virtual_property(&instance.properties,class,&index_ustr)
find_virtual_property(&instance.properties,class,index_str)
))
{
Some(rbx_types::Variant::Int32(val))=>return val.into_lua(lua),
@ -276,9 +277,6 @@ impl mlua::UserData for Instance{
});
methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(Instance,mlua::String,mlua::Value)|{
let index_str=&*index.to_str()?;
let Some(index_ustr)=Ustr::from_existing(index_str)else{
return Ok(())
};
dom_mut(lua,|dom|{
let instance=this.get_mut(dom)?;
let db=rbx_reflection_database::get();
@ -288,6 +286,9 @@ impl mlua::UserData for Instance{
).ok_or_else(||
mlua::Error::runtime(format!("Property '{index_str}' missing on class '{}'",class.name))
)?;
// the index is known to be a real property at this point
// allow creating a permanent ustr (memory leak)
let index_ustr=rbx_dom_weak::ustr(index_str);
match &property.data_type{
rbx_reflection::DataType::Value(rbx_types::VariantType::Vector3)=>{
let typed_value:Vector3=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected Userdata"))?.borrow()?;
@ -469,7 +470,7 @@ static VIRTUAL_PROPERTY_DATABASE:VPD=phf::phf_map!{
fn find_virtual_property(
properties:&rbx_dom_weak::UstrMap<rbx_types::Variant>,
class:&rbx_reflection::ClassDescriptor,
index:&Ustr,
index:&str,
)->Option<rbx_types::Variant>{
//Find virtual property
let class_virtual_properties=VIRTUAL_PROPERTY_DATABASE.get(&class.name)?;