avm2: Remove `void`'s ClassObject

This commit is contained in:
Lord-McSweeney 2024-06-21 11:14:21 -07:00 committed by Lord-McSweeney
parent f81136af2c
commit 0d637d34dd
4 changed files with 12 additions and 31 deletions

View File

@ -66,7 +66,7 @@ pub struct SystemClasses<'gc> {
pub number: ClassObject<'gc>,
pub int: ClassObject<'gc>,
pub uint: ClassObject<'gc>,
pub void: ClassObject<'gc>,
pub void_def: Class<'gc>,
pub namespace: ClassObject<'gc>,
pub array: ClassObject<'gc>,
pub movieclip: ClassObject<'gc>,
@ -198,7 +198,7 @@ impl<'gc> SystemClasses<'gc> {
number: object,
int: object,
uint: object,
void: object,
void_def: object.inner_class_definition(),
namespace: object,
array: object,
movieclip: object,
@ -604,9 +604,10 @@ pub fn load_player_globals<'gc>(
);
avm2_system_class!(array, activation, array::create_class(activation), script);
// TODO: this should _not_ be exposed as a ClassObject, getDefinitionByName etc.
// it should only be visible as an type for typecheck/cast purposes.
avm2_system_class!(void, activation, void::create_class(activation), script);
// void doesn't have a ClassObject
let void_def = void::create_class(activation);
activation.avm2().system_classes.as_mut().unwrap().void_def = void_def;
domain.export_class(void_def.name(), void_def, mc);
avm2_system_class!(
generic_vector,

View File

@ -1,6 +1,3 @@
// note: this should be a ClassObject-less class,
// with only the instance side.
use crate::avm2::activation::Activation;
use crate::avm2::class::Class;
use crate::avm2::method::Method;
@ -14,34 +11,17 @@ fn void_init<'gc>(
_this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
// FIXME: `void` should not have a ClassObject
// (this method should be unreachable)
Ok(Value::Undefined)
unreachable!()
}
pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> Class<'gc> {
let mc = activation.context.gc_context;
// FIXME: `void` should have neither a vtable nor a c_class
let class = Class::new(
let class = Class::custom_new(
QName::new(activation.avm2().public_namespace_base_version, "void"),
None,
Method::from_builtin(void_init, "", mc),
Method::from_builtin(void_init, "", mc),
activation.avm2().classes().class.inner_class_definition(),
mc,
);
class.mark_traits_loaded(activation.context.gc_context);
class
.init_vtable(&mut activation.context)
.expect("Native class's vtable should initialize");
let c_class = class.c_class().expect("Class::new returns an i_class");
c_class.mark_traits_loaded(activation.context.gc_context);
c_class
.init_vtable(&mut activation.context)
.expect("Native class's vtable should initialize");
class
}

View File

@ -99,7 +99,7 @@ impl<'gc> OptValue<'gc> {
|| self.class == Some(classes.uint.inner_class_definition())
|| self.class == Some(classes.number.inner_class_definition())
|| self.class == Some(classes.boolean.inner_class_definition())
|| self.class == Some(classes.void.inner_class_definition())
|| self.class == Some(classes.void_def)
}
pub fn merged_with(self, other: OptValue<'gc>) -> OptValue<'gc> {
@ -262,7 +262,7 @@ pub fn optimize<'gc>(
.classes()
.function
.inner_class_definition(),
void: activation.avm2().classes().void.inner_class_definition(),
void: activation.avm2().classes().void_def,
namespace: activation
.avm2()
.classes()

View File

@ -1013,7 +1013,7 @@ impl<'gc> Value<'gc> {
}
if matches!(self, Value::Undefined) || matches!(self, Value::Null) {
if class == activation.avm2().classes().void.inner_class_definition() {
if class == activation.avm2().classes().void_def {
return Ok(Value::Undefined);
}
return Ok(Value::Null);
@ -1110,7 +1110,7 @@ impl<'gc> Value<'gc> {
}
if let Value::Undefined = self {
if type_object == activation.avm2().classes().void.inner_class_definition() {
if type_object == activation.avm2().classes().void_def {
return true;
}
}