avm2: Use SystemClassDefs to look up builtin classes in a few more places

This commit is contained in:
Lord-McSweeney 2024-09-06 10:17:35 -07:00 committed by Lord-McSweeney
parent 96a8fe65b3
commit ee996cd433
12 changed files with 89 additions and 77 deletions

View File

@ -2026,8 +2026,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
}
fn op_check_filter(&mut self) -> Result<FrameControl<'gc>, Error<'gc>> {
let xml = self.avm2().classes().xml.inner_class_definition();
let xml_list = self.avm2().classes().xml_list.inner_class_definition();
let xml = self.avm2().class_defs().xml;
let xml_list = self.avm2().class_defs().xml_list;
let value = self.pop_stack().coerce_to_object_or_typeerror(self, None)?;
if value.is_of_type(xml) || value.is_of_type(xml_list) {
@ -2748,11 +2748,11 @@ impl<'a, 'gc> Activation<'a, 'gc> {
Value::Bool(_) => "boolean",
Value::Number(_) | Value::Integer(_) => "number",
Value::Object(o) => {
let classes = self.avm2().classes();
let classes = self.avm2().class_defs();
match o {
Object::FunctionObject(_) => {
if o.instance_class() == classes.function.inner_class_definition() {
if o.instance_class() == classes.function {
"function"
} else {
// Subclasses always have a typeof = "object"
@ -2760,8 +2760,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
}
}
Object::XmlObject(_) | Object::XmlListObject(_) => {
if o.instance_class() == classes.xml_list.inner_class_definition()
|| o.instance_class() == classes.xml.inner_class_definition()
if o.instance_class() == classes.xml_list
|| o.instance_class() == classes.xml
{
"xml"
} else {

View File

@ -78,7 +78,7 @@ pub fn serialize_value<'gc>(
}
} else if let Some(vec) = o.as_vector_storage() {
let val_type = vec.value_type();
if val_type == Some(activation.avm2().classes().int.inner_class_definition()) {
if val_type == Some(activation.avm2().class_defs().int) {
let int_vec: Vec<_> = vec
.iter()
.map(|v| {
@ -87,9 +87,7 @@ pub fn serialize_value<'gc>(
})
.collect();
Some(AmfValue::VectorInt(int_vec, vec.is_fixed()))
} else if val_type
== Some(activation.avm2().classes().uint.inner_class_definition())
{
} else if val_type == Some(activation.avm2().class_defs().uint) {
let uint_vec: Vec<_> = vec
.iter()
.map(|v| {
@ -98,9 +96,7 @@ pub fn serialize_value<'gc>(
})
.collect();
Some(AmfValue::VectorUInt(uint_vec, vec.is_fixed()))
} else if val_type
== Some(activation.avm2().classes().number.inner_class_definition())
{
} else if val_type == Some(activation.avm2().class_defs().number) {
let num_vec: Vec<_> = vec
.iter()
.map(|v| {
@ -388,7 +384,7 @@ pub fn deserialize_value<'gc>(
let storage = VectorStorage::from_values(
vec.iter().map(|v| (*v).into()).collect(),
*is_fixed,
Some(activation.avm2().classes().number.inner_class_definition()),
Some(activation.avm2().class_defs().number),
);
VectorObject::from_vector(storage, activation)?.into()
}
@ -396,7 +392,7 @@ pub fn deserialize_value<'gc>(
let storage = VectorStorage::from_values(
vec.iter().map(|v| (*v).into()).collect(),
*is_fixed,
Some(activation.avm2().classes().uint.inner_class_definition()),
Some(activation.avm2().class_defs().uint),
);
VectorObject::from_vector(storage, activation)?.into()
}
@ -404,7 +400,7 @@ pub fn deserialize_value<'gc>(
let storage = VectorStorage::from_values(
vec.iter().map(|v| (*v).into()).collect(),
*is_fixed,
Some(activation.avm2().classes().int.inner_class_definition()),
Some(activation.avm2().class_defs().int),
);
VectorObject::from_vector(storage, activation)?.into()
}

View File

@ -180,6 +180,19 @@ pub struct SystemClassDefs<'gc> {
pub function: Class<'gc>,
pub void: Class<'gc>,
pub array: Class<'gc>,
pub boolean: Class<'gc>,
pub int: Class<'gc>,
pub generic_vector: Class<'gc>,
pub namespace: Class<'gc>,
pub number: Class<'gc>,
pub string: Class<'gc>,
pub uint: Class<'gc>,
pub xml: Class<'gc>,
pub xml_list: Class<'gc>,
pub bitmap: Class<'gc>,
pub bitmapdata: Class<'gc>,
pub igraphicsdata: Class<'gc>,
pub graphicsbitmapfill: Class<'gc>,
pub graphicsendfill: Class<'gc>,
@ -323,6 +336,19 @@ impl<'gc> SystemClassDefs<'gc> {
void,
// temporary initialization
array: object,
boolean: object,
int: object,
generic_vector: object,
namespace: object,
number: object,
string: object,
uint: object,
xml: object,
xml_list: object,
bitmap: object,
bitmapdata: object,
igraphicsdata: object,
graphicsbitmapfill: object,
graphicsendfill: object,
@ -448,6 +474,9 @@ macro_rules! avm2_system_class {
let sc = $activation.avm2().system_classes.as_mut().unwrap();
sc.$field = class_object;
let scd = $activation.avm2().system_class_defs.as_mut().unwrap();
scd.$field = class_object.inner_class_definition();
};
}
@ -940,6 +969,10 @@ fn load_playerglobal<'gc>(
avm2_system_class_defs_playerglobal!(
&mut *activation,
[
("", "XML", xml),
("", "XMLList", xml_list),
("flash.display", "Bitmap", bitmap),
("flash.display", "BitmapData", bitmapdata),
("flash.display", "IGraphicsData", igraphicsdata),
("flash.display", "GraphicsBitmapFill", graphicsbitmapfill),
("flash.display", "GraphicsEndFill", graphicsendfill),

View File

@ -19,7 +19,7 @@ pub fn bitmap_allocator<'gc>(
class: ClassObject<'gc>,
activation: &mut Activation<'_, 'gc>,
) -> Result<Object<'gc>, Error<'gc>> {
let bitmap_cls = activation.avm2().classes().bitmap.inner_class_definition();
let bitmap_cls = activation.avm2().class_defs().bitmap;
let bitmapdata_cls = activation.context.avm2.classes().bitmapdata;
let mut class_def = Some(class.inner_class_definition());

View File

@ -370,7 +370,7 @@ pub fn get_vector<'gc>(
height,
);
let value_type = activation.avm2().classes().uint.inner_class_definition();
let value_type = activation.avm2().class_defs().uint;
let new_storage = VectorStorage::from_values(pixels, false, Some(value_type));
return Ok(VectorObject::from_vector(new_storage, activation)?.into());

View File

@ -123,7 +123,7 @@ pub fn get_qualified_definition_names<'gc>(
.map(|name| Value::String(name.to_qualified_name(activation.context.gc_context)))
.collect(),
false,
Some(activation.avm2().classes().string.inner_class_definition()),
Some(activation.avm2().class_defs().string),
);
let name_vector = VectorObject::from_vector(storage, activation)?;

View File

@ -235,13 +235,12 @@ impl<'gc> AvmSerializer<'gc> {
)?));
}
self.obj_stack.push(obj);
let value =
if obj.is_of_type(activation.avm2().classes().array.inner_class_definition()) {
// TODO: Vectors
self.serialize_iterable(activation, obj)?
} else {
self.serialize_object(activation, obj)?
};
let value = if obj.is_of_type(activation.avm2().class_defs().array) {
// TODO: Vectors
self.serialize_iterable(activation, obj)?
} else {
self.serialize_object(activation, obj)?
};
self.obj_stack
.pop()
.expect("Stack underflow during JSON serialization");

View File

@ -126,11 +126,7 @@ impl<'gc> ScriptObject<'gc> {
// can observe (the lack of) it.
let base = ScriptObjectWrapper(Gc::new(
mc,
ScriptObjectData::custom_new(
activation.avm2().classes().object.inner_class_definition(),
None,
vt,
),
ScriptObjectData::custom_new(activation.avm2().class_defs().object, None, vt),
));
ScriptObject(base.0).into()

View File

@ -93,14 +93,14 @@ impl<'gc> OptValue<'gc> {
return true;
}
let classes = activation.avm2().classes();
let class_defs = activation.avm2().class_defs();
// Primitives are always not-null
self.class == Some(classes.int.inner_class_definition())
|| 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(activation.avm2().class_defs().void)
self.class == Some(class_defs.int)
|| self.class == Some(class_defs.uint)
|| self.class == Some(class_defs.number)
|| self.class == Some(class_defs.boolean)
|| self.class == Some(class_defs.void)
}
pub fn merged_with(self, other: OptValue<'gc>) -> OptValue<'gc> {
@ -332,24 +332,16 @@ pub fn optimize<'gc>(
pub namespace: Class<'gc>,
}
let types = Types {
object: activation.avm2().classes().object.inner_class_definition(),
int: activation.avm2().classes().int.inner_class_definition(),
uint: activation.avm2().classes().uint.inner_class_definition(),
number: activation.avm2().classes().number.inner_class_definition(),
boolean: activation.avm2().classes().boolean.inner_class_definition(),
string: activation.avm2().classes().string.inner_class_definition(),
array: activation.avm2().classes().array.inner_class_definition(),
function: activation
.avm2()
.classes()
.function
.inner_class_definition(),
object: activation.avm2().class_defs().object,
int: activation.avm2().class_defs().int,
uint: activation.avm2().class_defs().uint,
number: activation.avm2().class_defs().number,
boolean: activation.avm2().class_defs().boolean,
string: activation.avm2().class_defs().string,
array: activation.avm2().class_defs().array,
function: activation.avm2().class_defs().function,
void: activation.avm2().class_defs().void,
namespace: activation
.avm2()
.classes()
.namespace
.inner_class_definition(),
namespace: activation.avm2().class_defs().namespace,
};
let method_body = method

View File

@ -990,19 +990,19 @@ impl<'gc> Value<'gc> {
activation: &mut Activation<'_, 'gc>,
class: Class<'gc>,
) -> Result<Value<'gc>, Error<'gc>> {
if class == activation.avm2().classes().int.inner_class_definition() {
if class == activation.avm2().class_defs().int {
return Ok(self.coerce_to_i32(activation)?.into());
}
if class == activation.avm2().classes().uint.inner_class_definition() {
if class == activation.avm2().class_defs().uint {
return Ok(self.coerce_to_u32(activation)?.into());
}
if class == activation.avm2().classes().number.inner_class_definition() {
if class == activation.avm2().class_defs().number {
return Ok(self.coerce_to_number(activation)?.into());
}
if class == activation.avm2().classes().boolean.inner_class_definition() {
if class == activation.avm2().class_defs().boolean {
return Ok(self.coerce_to_boolean().into());
}
@ -1013,7 +1013,7 @@ impl<'gc> Value<'gc> {
return Ok(Value::Null);
}
if class == activation.avm2().classes().string.inner_class_definition() {
if class == activation.avm2().class_defs().string {
return Ok(self.coerce_to_string(activation)?.into());
}
@ -1093,13 +1093,13 @@ impl<'gc> Value<'gc> {
activation: &mut Activation<'_, 'gc>,
type_object: Class<'gc>,
) -> bool {
if type_object == activation.avm2().classes().number.inner_class_definition() {
if type_object == activation.avm2().class_defs().number {
return self.is_number();
}
if type_object == activation.avm2().classes().uint.inner_class_definition() {
if type_object == activation.avm2().class_defs().uint {
return self.is_u32();
}
if type_object == activation.avm2().classes().int.inner_class_definition() {
if type_object == activation.avm2().class_defs().int {
return self.is_i32();
}

View File

@ -118,11 +118,11 @@ impl<'gc> VectorStorage<'gc> {
/// Get the default value for this vector.
pub fn default(&self, activation: &mut Activation<'_, 'gc>) -> Value<'gc> {
if let Some(value_type) = self.value_type {
if value_type == activation.avm2().classes().int.inner_class_definition()
|| value_type == activation.avm2().classes().uint.inner_class_definition()
if value_type == activation.avm2().class_defs().int
|| value_type == activation.avm2().class_defs().uint
{
Value::Integer(0)
} else if value_type == activation.avm2().classes().number.inner_class_definition() {
} else if value_type == activation.avm2().class_defs().number {
Value::Number(0.0)
} else {
Value::Null
@ -234,11 +234,11 @@ impl<'gc> VectorStorage<'gc> {
if let Some(v) = self.storage.pop() {
Ok(v)
} else if let Some(value_type) = self.value_type() {
if value_type == activation.avm2().classes().uint.inner_class_definition()
|| value_type == activation.avm2().classes().int.inner_class_definition()
if value_type == activation.avm2().class_defs().uint
|| value_type == activation.avm2().class_defs().int
{
Ok(Value::Integer(0))
} else if value_type == activation.avm2().classes().number.inner_class_definition() {
} else if value_type == activation.avm2().class_defs().number {
Ok(Value::Number(0.0))
} else {
Ok(Value::Undefined)
@ -280,11 +280,11 @@ impl<'gc> VectorStorage<'gc> {
if !self.storage.is_empty() {
Ok(self.storage.remove(0))
} else if let Some(value_type) = self.value_type() {
if value_type == activation.avm2().classes().uint.inner_class_definition()
|| value_type == activation.avm2().classes().int.inner_class_definition()
if value_type == activation.avm2().class_defs().uint
|| value_type == activation.avm2().class_defs().int
{
Ok(Value::Integer(0))
} else if value_type == activation.avm2().classes().number.inner_class_definition() {
} else if value_type == activation.avm2().class_defs().number {
Ok(Value::Number(0.0))
} else {
Ok(Value::Undefined)

View File

@ -65,13 +65,9 @@ impl<'gc> BitmapClass<'gc> {
context: &mut UpdateContext<'gc>,
) -> Option<Self> {
let class_definition = class.inner_class_definition();
if class_definition
.has_class_in_chain(context.avm2.classes().bitmap.inner_class_definition())
{
if class_definition.has_class_in_chain(context.avm2.class_defs().bitmap) {
Some(BitmapClass::Bitmap(class))
} else if class_definition
.has_class_in_chain(context.avm2.classes().bitmapdata.inner_class_definition())
{
} else if class_definition.has_class_in_chain(context.avm2.class_defs().bitmapdata) {
Some(BitmapClass::BitmapData(class))
} else {
None