Skip to content
7 changes: 4 additions & 3 deletions core/build_playerglobal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
panic!("ASC should calculate slot ids for all slots; cannot apply NativeAccessible without a compiler-calculated slot id")
} else {
// Slots are 1-indexed!
let slot_id = slot_id - 1;
let slot_id = slot_id as usize - 1;

let (trait_name, const_name) =
rust_path_and_trait_name(&abc, trait_, parent);
Expand All @@ -472,7 +472,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
.entry(trait_name)
.or_default()
.push(quote! {
pub const #const_name: u32 = #slot_id;
pub const #const_name: usize = #slot_id;
});
}
}
Expand All @@ -490,6 +490,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
// add 1 if it's a class method, or subtract 2 if it's
// an instance method.
let disp_id = if is_class { disp_id + 1 } else { disp_id - 2 };
let disp_id = disp_id as usize;

let (trait_name, const_name) =
rust_path_and_trait_name(&abc, trait_, parent);
Expand All @@ -506,7 +507,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
.entry(trait_name)
.or_default()
.push(quote! {
pub const #const_name: u32 = #disp_id;
pub const #const_name: usize = #disp_id;
});
}
}
Expand Down
12 changes: 6 additions & 6 deletions core/src/avm2/activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@

fn op_call_method(
&mut self,
index: u32,
index: usize,
arg_count: u32,
push_return_value: bool,
) -> Result<(), Error<'gc>> {
Expand Down Expand Up @@ -1628,7 +1628,7 @@
Ok(())
}

fn op_get_slot(&mut self, index: u32) -> Result<(), Error<'gc>> {
fn op_get_slot(&mut self, index: usize) -> Result<(), Error<'gc>> {
let stack_top = self.stack.stack_top();

let object = stack_top
Expand All @@ -1647,7 +1647,7 @@
Ok(())
}

fn op_set_slot(&mut self, index: u32) -> Result<(), Error<'gc>> {
fn op_set_slot(&mut self, index: usize) -> Result<(), Error<'gc>> {
let value = self.pop_stack();
let object = self
.pop_stack()
Expand All @@ -1660,7 +1660,7 @@
Ok(())
}

fn op_set_slot_no_coerce(&mut self, index: u32) -> Result<(), Error<'gc>> {
fn op_set_slot_no_coerce(&mut self, index: usize) -> Result<(), Error<'gc>> {
let value = self.pop_stack();
let object = self
.pop_stack()
Expand All @@ -1673,7 +1673,7 @@
Ok(())
}

fn op_set_global_slot(&mut self, index: u32) -> Result<(), Error<'gc>> {
fn op_set_global_slot(&mut self, index: usize) -> Result<(), Error<'gc>> {

Check warning on line 1676 in core/src/avm2/activation.rs

View workflow job for this annotation

GitHub Actions / Coverage Report

Coverage

Uncovered line (1676)
let value = self.pop_stack();

self.global_scope()
Expand Down Expand Up @@ -1712,7 +1712,7 @@
Ok(())
}

fn op_construct_slot(&mut self, index: u32, arg_count: u32) -> Result<(), Error<'gc>> {
fn op_construct_slot(&mut self, index: usize, arg_count: u32) -> Result<(), Error<'gc>> {
let args = self.stack.get_args(arg_count as usize);
let source = self
.pop_stack()
Expand Down
29 changes: 23 additions & 6 deletions core/src/avm2/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::avm2::object::{scriptobject_allocator, ClassObject, Object};
use crate::avm2::script::TranslationUnit;
use crate::avm2::traits::{Trait, TraitKind};
use crate::avm2::value::Value;
use crate::avm2::vtable::VTable;
use crate::avm2::vtable::{VTable, VTableInitError};
use crate::avm2::Error;
use crate::avm2::Multiname;
use crate::avm2::Namespace;
Expand Down Expand Up @@ -321,9 +321,13 @@ impl<'gc> Class<'gc> {
let c_class = Class(Gc::new(mc, c_class));

i_class.link_with_c_class(mc, c_class);
i_class.init_vtable_with_interfaces(context, Box::new([]));
i_class
.init_vtable_with_interfaces(context, Box::new([]))
.expect("Specialized vector has no traits on itself");

c_class.init_vtable_with_interfaces(context, Box::new([]));
c_class
.init_vtable_with_interfaces(context, Box::new([]))
.expect("Specialized vector has no traits on itself");

let write = unlock!(Gc::write(mc, this.0), ClassData, cell);
write.borrow_mut().applications.insert(Some(param), i_class);
Expand Down Expand Up @@ -828,11 +832,22 @@ impl<'gc> Class<'gc> {
Ok(())
}

/// Initialize the vtable and interfaces of this Class with an empty vtable
/// and no interfaces. This is useful for classes that are known to not have
/// any traits or interfaces.
pub fn init_empty_vtable(self, mc: &Mutation<'gc>) {
let write = Gc::write(mc, self.0);

let _ = unlock!(write, ClassData, all_interfaces).set(Box::new([]));
let _ = unlock!(write, ClassData, vtable).set(VTable::empty(mc));
}

/// Initialize the vtable and interfaces of this Class.
pub fn init_vtable(self, activation: &mut Activation<'_, 'gc>) -> Result<(), Error<'gc>> {
let interfaces = self.gather_interfaces(activation)?;

self.init_vtable_with_interfaces(activation.context, interfaces);
self.init_vtable_with_interfaces(activation.context, interfaces)
.map_err(|e| e.into_avm(activation))?;

Ok(())
}
Expand All @@ -844,7 +859,7 @@ impl<'gc> Class<'gc> {
self,
context: &mut UpdateContext<'gc>,
interfaces: Box<[Class<'gc>]>,
) {
) -> Result<(), VTableInitError> {
if self.0.traits.get().is_none() {
panic!(
"Attempted to initialize vtable on a class that did not have its traits loaded yet"
Expand All @@ -863,7 +878,9 @@ impl<'gc> Class<'gc> {
None,
self.0.super_class.map(|c| c.vtable()),
context,
));
)?);

Ok(())
}

/// Associate all the methods defined on this class with the specified
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ pub fn make_error_1025<'gc>(activation: &mut Activation<'_, 'gc>, index: u32) ->
#[cold]
pub fn make_error_1026<'gc>(
activation: &mut Activation<'_, 'gc>,
slot_id: u32,
slot_id: usize,
slot_count: usize,
) -> Error<'gc> {
let err = verify_error(
Expand Down
8 changes: 2 additions & 6 deletions core/src/avm2/globals/avmplus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,6 @@ fn describe_internal_body<'gc>(
_ => unreachable!(),
};

let trait_metadata = vtable.get_metadata_for_slot(*slot_id);

let variable = ScriptObject::new_object(activation);
variable.set_dynamic_property(istr!("name"), prop_name.into(), activation.gc());
variable.set_dynamic_property(
Expand All @@ -231,7 +229,7 @@ fn describe_internal_body<'gc>(

if flags.contains(DescribeTypeFlags::INCLUDE_METADATA) {
let metadata_object = ArrayObject::empty(activation);
if let Some(metadata) = trait_metadata {
if let Some(metadata) = vtable.get_metadata_for_slot(*slot_id) {
write_metadata(metadata_object, metadata, activation);
}
variable.set_dynamic_property(
Expand Down Expand Up @@ -274,8 +272,6 @@ fn describe_internal_body<'gc>(

let declared_by_name = declared_by.dollar_removed_name(mc).to_qualified_name(mc);

let trait_metadata = vtable.get_metadata_for_disp(*disp_id);

let method_obj = ScriptObject::new_object(activation);

method_obj.set_dynamic_property(istr!("name"), prop_name.into(), activation.gc());
Expand Down Expand Up @@ -307,7 +303,7 @@ fn describe_internal_body<'gc>(

if flags.contains(DescribeTypeFlags::INCLUDE_METADATA) {
let metadata_object = ArrayObject::empty(activation);
if let Some(metadata) = trait_metadata {
if let Some(metadata) = vtable.get_metadata_for_disp(*disp_id) {
write_metadata(metadata_object, metadata, activation);
}
method_obj.set_dynamic_property(
Expand Down
2 changes: 1 addition & 1 deletion core/src/avm2/globals/flash/display/display_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ pub fn object_to_rectangle<'gc>(
activation: &mut Activation<'_, 'gc>,
object: Object<'gc>,
) -> Result<Rectangle<Twips>, Error<'gc>> {
const SLOTS: &[u32] = &[
const SLOTS: &[usize] = &[
rectangle_slots::X,
rectangle_slots::Y,
rectangle_slots::WIDTH,
Expand Down
8 changes: 4 additions & 4 deletions core/src/avm2/globals/flash/events/mouse_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ pub fn update_after_event<'gc>(
pub(super) fn local_to_stage_x<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Object<'gc>,
slot_x: u32,
slot_y: u32,
slot_x: usize,
slot_y: usize,
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(evt) = this.as_event() {
let local_x = this.get_slot(slot_x).coerce_to_number(activation)?;
Expand All @@ -66,8 +66,8 @@ pub(super) fn local_to_stage_x<'gc>(
pub(super) fn local_to_stage_y<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Object<'gc>,
slot_x: u32,
slot_y: u32,
slot_x: usize,
slot_y: usize,
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(evt) = this.as_event() {
let local_x = this.get_slot(slot_x).coerce_to_number(activation)?;
Expand Down
4 changes: 3 additions & 1 deletion core/src/avm2/globals/global_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ pub fn create_class<'gc>(

// `global` classes have no interfaces, so use `init_vtable_with_interfaces`
// and pass an empty list
class.init_vtable_with_interfaces(activation.context, Box::new([]));
class
.init_vtable_with_interfaces(activation.context, Box::new([]))
.map_err(|e| e.into_avm(activation))?;

class.mark_builtin_type(BuiltinType::ScriptTraits);

Expand Down
5 changes: 2 additions & 3 deletions core/src/avm2/globals/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> Class<'gc> {
);
class.set_attributes(ClassAttributes::FINAL | ClassAttributes::SEALED);

// The `null` class has no interfaces, so use `init_vtable_with_interfaces`
// and pass an empty list
class.init_vtable_with_interfaces(activation.context, Box::new([]));
// The `null` class has no interfaces or traits, so use `init_empty_vtable`
class.init_empty_vtable(activation.gc());

class
}
5 changes: 2 additions & 3 deletions core/src/avm2/globals/void.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> Class<'gc> {
);
class.set_attributes(ClassAttributes::FINAL | ClassAttributes::SEALED);

// The `void` class has no interfaces, so use `init_vtable_with_interfaces`
// and pass an empty list
class.init_vtable_with_interfaces(activation.context, Box::new([]));
// The `void` class has no interfaces or traits, so use `init_empty_vtable`
class.init_empty_vtable(activation.gc());

class
}
10 changes: 5 additions & 5 deletions core/src/avm2/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
/// Retrieve a slot by its index.
#[no_dynamic]
#[inline(always)]
fn get_slot(self, id: u32) -> Value<'gc> {
fn get_slot(self, id: usize) -> Value<'gc> {
let base = self.base();

base.get_slot(id)
Expand All @@ -409,7 +409,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
#[no_dynamic]
fn set_slot(
self,
id: u32,
id: usize,
value: Value<'gc>,
activation: &mut Activation<'_, 'gc>,
) -> Result<(), Error<'gc>> {
Expand All @@ -422,7 +422,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
}

#[no_dynamic]
fn set_slot_no_coerce(self, id: u32, value: Value<'gc>, mc: &Mutation<'gc>) {
fn set_slot_no_coerce(self, id: usize, value: Value<'gc>, mc: &Mutation<'gc>) {
let base = self.base();

base.set_slot(id, value, mc);
Expand Down Expand Up @@ -580,7 +580,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
fn install_bound_method(
&self,
mc: &Mutation<'gc>,
disp_id: u32,
disp_id: usize,
function: FunctionObject<'gc>,
) {
let base = self.base();
Expand Down Expand Up @@ -691,7 +691,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
}

#[no_dynamic]
fn get_bound_method(&self, id: u32) -> Option<FunctionObject<'gc>> {
fn get_bound_method(&self, id: usize) -> Option<FunctionObject<'gc>> {
let base = self.base();
base.get_bound_method(id)
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/avm2/object/class_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ impl<'gc> ClassObject<'gc> {
self.superclass_object().map(|cls| cls.instance_vtable()),
activation.context,
);
let vtable = vtable.expect("ClassObject VTable should be valid");

unlock!(Gc::write(mc, self.0), ClassObjectData, instance_vtable).set(vtable);
}
Expand Down Expand Up @@ -254,6 +255,7 @@ impl<'gc> ClassObject<'gc> {
Some(class_classobject.instance_vtable()),
activation.gc(),
);
let class_vtable = class_vtable.expect("ClassObject VTable should be valid");

self.set_vtable(activation.gc(), class_vtable);
}
Expand Down Expand Up @@ -606,7 +608,7 @@ impl<'gc> ClassObject<'gc> {
self,
activation: &mut Activation<'_, 'gc>,
receiver: Object<'gc>,
disp_id: u32,
disp_id: usize,
arguments: FunctionArgs<'_, 'gc>,
) -> Result<Value<'gc>, Error<'gc>> {
let full_method = self.instance_vtable().get_full_method(disp_id).unwrap();
Expand Down
Loading
Loading